从C ++函数调用Objective-C方法?

时间:2012-03-28 15:03:01

标签: objective-c objective-c++

我从一个关于如何从C ++方法调用objective-c方法的问题的答案中选择了这个

这很好。

的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);
}

现在如果我使用

之类的东西

的MyObject-C-Interface.h

 #ifndef __MYOBJECT_C_INTERFACE_H__
 #define __MYOBJECT_C_INTERFACE_H__ 1

 @class MyObject;

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

 #endif

我的问题是,如果我使用 MyObject * myObjectInstance ,而不是使用 void * myObjectInstance

它给出了这个错误 错误:期望unqualified-id [1] :@class line和
错误:在函数原型的行中使用未声明的标识符'MyObject'[3]

帮助!

1 个答案:

答案 0 :(得分:3)

链接错误:

链接错误与C ++破坏函数名称的方式有关,而C不会这样做。这实际上与Objective-C无关。具体地,

int MyObjectDoSomethingWith (void *myObjectInstance, void *parameter);
C或Objective-C(在OSX上)中的

使用名称_MyObjectDoSomethingWith导出到链接器。使用C ++或Objective-C ++编译器编译的具有相同名称和原型的函数被链接器称为__Z23MyObjectDoSomethingWithPvS_。这称为“名称修改”,它对参数类型进行编码。否则,函数重载将不起作用,因为无法区分具有不同参数类型但具有相同名称的函数。要从C ++中调用C中定义的函数,您必须标记原型,以便预期C链接,并且不会破坏函数特定重载的名称。

您需要告诉C ++编译器使用extern "C"将其视为C函数,如下所示:

#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

或者像这样:

#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声明编译错误(请不要一次询问多个问题):

您正在尝试#include "MyObject-C-Interface.h",其中包含来自 MyCPPClass.cpp 的Objective-C @class前向声明,它将被编译为纯C ++。 Objective-C指令主要是C ++中的语法错误,所以你不能这样做。要在纯C ++或C中传递Objective-C对象,您需要使用id类型。您需要#include <objc/objc.h>,因为在{C或C ++中默认情况下未定义id

*此外,请不要在名称前添加两个下划线:__ - 保留此类名称。*