Reputation: 1972
I picked this up from an answer to a question on how to call objective-c method from C++ method
This runs fine.
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.mm
#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);
}
NOW if i use something like
MyObject-C-Interface.h
#ifndef __MYOBJECT_C_INTERFACE_H__
#define __MYOBJECT_C_INTERFACE_H__ 1
@class MyObject;
int MyObjectDoSomethingWith (MyObject* myObjectInstance, void *parameter);
#endif
My question is instead of using void *myObjectInstance if i use MyObject *myObjectInstance.
it gives this error
error: expected unqualified-id [1] : @class line and
error: use of undeclared identifier 'MyObject' [3] in function prototype's line
Help!!!!
Upvotes: 2
Views: 4309
Reputation: 23428
Link Error:
The link error is to do with the way C++ mangles function names, which C doesn't do. This actually has nothing to do with Objective-C. Specifically,
int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);
in C or Objective-C (on OSX) is exported to the linker using the name _MyObjectDoSomethingWith
. A function with the same name and prototype, compiled with a C++ or Objective-C++ compiler, is known to the linker as __Z23MyObjectDoSomethingWithPvS_
. This is called "name mangling", and it encodes the parameter types. Otherwise, function overloading wouldn't work, as functions with different parameter types but the same name couldn't be distinguished. To call a function defined in C from C++, you therefore have to mark the prototype such that C linkage is expected, and it won't mangle the name of that specific overload of the function.
You'll need to tell the C++ compiler to treat it as a C function using extern "C"
, either like this:
#ifndef MYOBJECT_C_INTERFACE_H
#define MYOBJECT_C_INTERFACE_H
#ifdef __cplusplus
extern "C" {
#endif
int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);
#ifdef __cplusplus
}
#endif
#endif
or like this:
#ifndef MYOBJECT_C_INTERFACE_H
#define MYOBJECT_C_INTERFACE_H
#ifdef __cplusplus
#define CFUN extern "C"
#else
#define CFUN
#endif
CFUN int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);
#endif
@class declaration compile error (please do not ask more than one question at a time):
You're trying to #include "MyObject-C-Interface.h"
, which contains an Objective-C @class
forward declaration, from MyCPPClass.cpp, which will be compiled as pure C++. Objective-C directives are mostly syntax errors in C++, so you can't do that. To pass around Objective-C objects in pure C++ or C, you will need to use the id
type. You'll need to #include <objc/objc.h>
for that, as id
isn't defined by default in C or C++.
*Also, please don't prefix your names with two underscores: __ - such names are reserved.*
Upvotes: 4