I have a class (EAGLView
) which calls a member function of a C++
class without problems. Now, the problem is that I need to call in that C++
class a objective-C
function
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
which I cannot do in C++
syntax.
I could wrap this Objective-C
call to the same Objective-C
class which in the first place called the C++ class, but then I need to somehow call that method from C++
, and I cannot figure out how to do it.
I tried to give a pointer to EAGLView
object to the C++ member function and include the "EAGLView.h
" in my C++
class header but I got 3999 errors..
So.. how should I do this? An example would be nice.. I only found pure C
examples of doing this.
Best Solution
You can mix C++ with Objective-C if you do it carefully. There are a few caveats but generally speaking they can be mixed. If you want to keep them separate, you can set up a standard C wrapper function that gives the Objective-C object a usable C-style interface from non-Objective-C code (pick better names for your files, I have picked these names for verbosity):
MyObject-C-Interface.h
MyObject.h
MyObject.mm
MyCPPClass.cpp
The wrapper function does not need to be in the same
.m
file as the Objective-C class, but the file that it does exist in needs to be compiled as Objective-C code. The header that declares the wrapper function needs to be included in both CPP and Objective-C code.(NOTE: if the Objective-C implementation file is given the extension ".m" it will not link under Xcode. The ".mm" extension tells Xcode to expect a combination of Objective-C and C++, i.e., Objective-C++.)
You can implement the above in an Object-Orientented manner by using the PIMPL idiom. The implementation is only slightly different. In short, you place the wrapper functions (declared in "MyObject-C-Interface.h") inside a class with a (private) void pointer to an instance of MyClass.
MyObject-C-Interface.h (PIMPL)
Notice the wrapper methods no longer require the void pointer to an instance of MyClass; it is now a private member of MyClassImpl. The init method is used to instantiate a MyClass instance;
MyObject.h (PIMPL)
MyObject.mm (PIMPL)
Notice that MyClass is instantiated with a call to MyClassImpl::init. You could instantiate MyClass in MyClassImpl's constructor, but that generally isn't a good idea. The MyClass instance is destructed from MyClassImpl's destructor. As with the C-style implementation, the wrapper methods simply defer to the respective methods of MyClass.
MyCPPClass.h (PIMPL)
MyCPPClass.cpp (PIMPL)
You now access calls to MyClass through a private implementation of MyClassImpl. This approach can be advantageous if you were developing a portable application; you could simply swap out the implementation of MyClass with one specific to the other platform ... but honestly, whether this is a better implementation is more a matter of taste and needs.