If you’ve noticed that there’s been a long time between this post and the previous one, you are right. My day job has been keeping me busy. But that’s why I can get on with the topic: mixing legacy C++ with Objective-C.
After trying things a few ways, I’m finding that one basic assumption difference between the languages can trip you up: the assumption about calling a method or function with an object pointer to zero (a.k.a. nil or null or NULL).
Since the C++ will generally be legacy code, its natural for Objective-C objects to wind up containing pointers to C++ objects. After that, its pretty easy to wind up calling C++ functions almost directly from accessors like:
result = [[CentralClass getSingleton] getOldObjectPtr]->legacyFunction();
This is functional, but from a solid-coding standpoint, it is too bug-prone and too hard to debug. If the above statement crashes, which part of it failed?
Objective-C assumes that calling member methods with nil object pointers is OK. (i.e., a nil ‘self’ pointer is not an error.) Any such attempt just automatically returns zero.
C++ however, assumes that member functions will never be called against a NULL pointer. (i.e., a NULL ‘this’ pointer.) Any such attempt will probably crash an iPhone with EXC_BAD_ACCESS.
My point here is you should put the pointer into a variable, then call the function from that variable:
LegacyClass* myObject = [[CentralClass getSingleton] getOldObjectPtr]; result = myObject->LegacyFunction();
Now the language assumptions are clearly separated. Nil pointers in the first line can be safely assumed to have zero method results. And the C++ in the second line can be more easily debugged if it fails. (And we can easily check our C++ pointer for NULL before calling its function.)
The crash from the C++ code will most likely happen when the member function tries to dereference a member variable. An instance’s member variable is held at an offset from the pointer, so if the pointer is zero, the member equates to an address that is near zero. Addresses near zero are invalid on the iOS.
So there you go, if you have to mix Objective-C and C++, avoid mixing them on the same line.