2

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!!!!

2
  • please check this link Commented Mar 28, 2012 at 15:59
  • Basically, just move MyObjectDoSomethingWith out of the MyObject @implementation. Commented Mar 28, 2012 at 16:30

1 Answer 1

4

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.*

Sign up to request clarification or add additional context in comments.

8 Comments

thanks for that but instead of id and void* can i use name of objective C interface to receive the same object
Not outside of Objective-C and Objective-C++.
but .h does not come outside of .m or .mm , if i receive it in MyObject* with #import"MyObject.h" then linker error comes otherwise with void* or id program builds and runs fine.
also you said it will poison my header to be used in that way only, but i am defining this function in a .mm therefore it should not give any error but error remains
@tusharfloyd no, you're including the header from a .cpp file, so you can't use Objective-C in it. I've updated the explanation for the link error. int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter); is NOT a C function when compiled with a C++ compiler, unless you specifically mark it as such.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.