Short version: I have a Qt/C++ to which I am having to add a limited amount of Cocoa/Objective-C code. I have changed the .cpp file to a .mm file and added the objective-c code/objects to said file, and it compiles and works. I now need a delegate for one of the objects I created- a NSPopUpButton (or, rather, the menu thereof) to be exact – and I’m stuck. How can I add a delegate for this object?
Details:
Files in question:
reportwindow.h, reportwindow.cpp RENAMED TO reportwindow.mm
-These are the files containing my original C++ implementation plus some objective-c code (open a NSSavePanel containing a NSPopUpButton). reportwindow.h is additionally included in a .cpp file, if that makes a difference.
menuHandler.h, menuHandler.mm
-these files contain a (currently empty) objective-c class that I was intending to use as a delegate
My first thought was that I could simply make the C++ class the delegate, but this obviously doesn’t work as straight C++ doesn’t understand delegation. I then thought I’d make a separate objective-c class as a NSMenuDelegate and add an instance of it as a member object to my C++ class. As I have been able to add other objective-c objects as members, I figured this should work. However, as soon as I included the header for my new objective-c class in the C++ class header file, I got several hundred errors about “expected unqualified-id before ‘@’ token” -from the apple header files (NSValue.h, NSObject.h, etc) So apparently that didn’t work, at least not as-is. I get the same result when including ANY cocoa header in my class header file.
I then thought I’d try a forward-declaration of the objective-c class (that is how I got the other objective-c objects working). however, this didn’t work either- if I declare it as “class myClassName” I get an error about re-defining the class as a different type of symbol (presumably c++ class vs objective-c protocol). If I try to forward declare it as @protocol myClassName, I get an error about “expected unqualified-id before ‘@’ token”. So how can I make this work?
Ok to answer your question:
It does make a difference. Any compilation unit (cpp file in this case) that is touching Objective-C code has to be renamed to .mm or .m. Including the header that in turn is including Objective-C stuff in a C++ file will lead to the problem that the C++ compiler sees Objective-C code which it cannot handle.
Renaming the cpp file to mm will select the Objective-C option during compilation (which isn’t when the file is named cpp or c) and hence allow to compile stuff with the Objective-C tokens (mainly “@” in your case).
An alternative would be not to include the Objective-C delegate class to your C++ class but rather include a pointer to your C++ class within the Objective-C delegate (i.e. implement it the other way around). This way you could arrange things such that the Objective-C code isn’t touching the C++ code.
Edit: Actually, I’d prefer the second suggestion. Here is an example:
DelegateClass.h:
DelegateClass.mm
And well the MyCPPClassHandlingStuff.h:
MyCPPClassHandlingStuff can be initialized from Objective-C but you cannot initialise any Objective-C class from C++ code there. If you need to use Objective-C in your C++ code, you would have to compile it as Objective-C (i.e. use an .mm file). I leave the .cpp details as an exercise for the reader 😉