views:

3943

answers:

5

Hi,

I have a class (EAGLView) which calls a method 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++ method 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.

A: 

You can mix C++ in with Objectiv-C (Objective C++). Write a C++ method in your Objective C++ class that simply calls [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer]; and call it from your C++.

I haven't tried it before my self, but give it a shot, and share the results with us.

hhafez
But the problem is that how can I call it... because if I include "EAGLview.h" in my C++ class I get thousands of errors.
juvenis
+6  A: 

You can compile your code as Objective-C++ - the simplest way is to rename your .cpp as .mm. It will then compile properly if you include EAGLView.h (you were getting so many errors because the C++ compiler didn't understand any of the Objective-C specific keywords), and you can (for the most part) mix Objective-C and C++ however you like.

Jesse Beder
I have already done the renaming
juvenis
Are you getting all of those compiler errors in *this* C++ file, or are they in some other C++ file that happens to include this C++ header?
Jesse Beder
It seems I cannot include the EAGLView.h in the C++ header file because then it for some reason expects that the Objective C code is C++, and does not understand @ + other symbols
juvenis
+2  A: 

You need to make your C++ file be treated as Objective-C++. You can do this in xcode by renaming foo.cpp to foo.mm (.mm is the obj-c++ extension). Then as others have said standard obj-c messaging syntax will work.

olliej
+5  A: 

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

#ifndef __MYOBJECT_C_INTERFACE_H__
#define __MYOBJECT_C_INTERFACE_H__ 1

int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);

#endif

MyObject.h

#import "MyObject-C-Interface.h"

@interface MyObject : NSObject
{
    int someVar;
}

- (int) doSomethingWith:(void *) aParameter;
@end

MyObject.m

#import "MyObject.h"

@implementation MyObject

int MyObjectDoSomethingWith (void *self, void *aParameter)
{
    return [(id) self doSomethingWith:aParameter];
}

- (int) doSomethingWith:(void *) aParameter
{
    // ... some code
    return 1;
}

@end

MyCPPClass.cpp

#include "MyCPPClass.h"
#include "MyObject-C-Interface.h"

int MyCPPClass::someMethod (void *objectiveCObject, void *aParameter)
{
    return MyObjectDoSomethingWith (objectiveCObject, aParameter);
}

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.

dreamlax
Hi, I tried it but I get linkage error saying symbol(s) not found. i.e. it can't find the MyObjectDoSomethingWith. any ideas?
ishaq
You might need to add `extern "C"` before the `int MyObjectDoSomethingWith`
dreamlax
tried that already, doesn't work and it makes sense because extern "C" is used when we want to call C++ function from C, in this case we are calling a C function from C++, no?
ishaq
+1  A: 

The easiest solution is to simply tell Xcode to compile everything as Objective C++.

Set your project or target settings for Compile Sources As to Objective C++ and recompile.

Then you can use C++ or Objective C everywhere, for example:

void CPPObject::Function( ObjectiveCObject* context, NSView* view )
{
   [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)view.layer]
}

This has the same affect as renaming all your source files from .cpp or .m to .mm.

There are two minor downsides to this: clang cannot analyse C++ source code; some relatively weird C code does not compile under C++.

Peter N Lewis
I'm just a little curious, when you compile everything as Objective-C++ do you get warnings about using C-style casts and/or other C++-specific warnings about valid C-style code?
dreamlax
Sure, you are programming in C++ so you'll be expected to behave appropriately - but as a general rule, C++ is a better C than C is, even if you never create a class. It wont let you do stupid things, and it lets you do nice things (like better constants and enums and such). You can still cast just the same (eg (CFFloat)x).
Peter N Lewis