我从一个关于如何从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]
帮助!
答案 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
。
*此外,请不要在名称前添加两个下划线:__ - 保留此类名称。*