Re: Help Mixing Objective-C & Objective-C++
Re: Help Mixing Objective-C & Objective-C++
- Subject: Re: Help Mixing Objective-C & Objective-C++
- From: Uli Kusterer <email@hidden>
- Date: Thu, 24 Feb 2011 11:16:11 +0100
On 23.02.2011, at 19:47, James Bucanek wrote:
> Specifically, I create an Objective-C++ class that contain C++ object references and types in its @interface declaration. How can I #import this into an Objective-C module? The Objective-C won't understand any of the C++ class names or types.
1) #include <objc/objc.h>, which is a C-language header that defines the "id" type.
2) Use #ifdef __cplusplus and/or #ifdef __OBJC__ to conditionally typedef your C++/ObjC object pointers to some other name, and use those typedefs in your public interfaces. But keep in mind not to use this on C++ functions and member functions, as a void* could result in a differently-mangled name than MyObjCClass*, and then you'd have two definitions of the same class with different vtables, which is asking for weird crashes.
3) Keep in mind you can forward-declare C++ classes as structs. If your member variables are all pointers, the C compiler will see them as straight classes and won't complain, but you'll get the correct types when compiling C++.
4) Replace all your foreign-language instance variables with a pointer to a struct, which you then calloc() or new in your constructor (and free()/delete in destructor, of course). That way, nobody outside sees the actual ivars or has to compile in their language. You'll have to hand-craft all your accessors, of course, but you'd likely have to do that anyway. In addition, it's a nice technique to circumvent the fragile base class problem in the old 32-bit runtime if you keep *all* ivars in there. Useful if these classes go in a framework.
5) As a variation on #4, you can also use a private subclass of your base class (like NSString does) and declare all ivars in there, then make the public header's alloc/init and factory methods create objects of that subclass.
6) Use categories in a separate header if you want to expose ObjC++-specific API to those that use C++ without screwing pure ObjC code.
7) If you define ObjC types as id or C++ types as void, use macros (or even better, accessors) to do the typecasting for you more safely. E.g. #define M_MY_OBJECT ((MyObject*)mMyObject) so you can say M_MY_OBJECT->CallMethod() instead of littering possibly mis-typed typecasts throughout your code. D.R.Y.
> Conversely, when #importing Objective-C interfaces in an Objective-C++ module, do I extern "C" { ... } the whole thing?
Yes, that's generally what I do. The ObjC parts won't be affected, but that way the C function prototypes won't get mis-interpreted as being C++ name-mangled functions. Also keep in mind that, while C++ lets you say void MyFoo(); you need to specify void MyFoo( void ); to have a valid prototype in straight C (and ObjC). Otherwise you'll get a warning about missing prototypes.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden