我已将一个 obj-c 类(.mm 和 2 个 header )添加到我当前的 Xcode 4.6 项目中。一个头文件具有调用 obj-c 类的原型(prototype),另一个定义了 .mm 类。这是它的样子。
我的接口(interface).h
#ifndef MYINTERFACE_H
#define MYINTERFACE_H
BOOL LaunchApp(CAtlString exePath);
#endif
myLaunchClass.h
#import "myinterface.h"
@interface myLaunchClass : NSObject
-(BOOL) LaunchApp:(CAtlString)exePath;
@end
myLaunchClass.mm
@import "myLaunchClass.h"
@implementation myLaunchClass
-(BOOL) LaunchApp:(CAtlString)exePath
{
....
return someCondition;
}
@end
从那里它编译得很好。我将 .mm 文件添加到构建阶段中的目标,并将标题位置添加到build设置中的标题搜索路径。
当我在我的 .cpp 文件中包含头文件时 (#include "myinterface.h"
) 我没有错误。但是,当我调用我的函数 (::LaunchApp(exePath);
) 时,出现链接器错误。
错误
Undefined symbols for architecture i386:
"LaunchApp(CAtlString)", referenced from:
myCppFile::myCppFunction() const in myCppFile.o
ld: symbol(s) not found for architecture i386
有什么想法吗?我认为这对 Mac 开发人员来说一定是一个明显的错误,但我对 Mac 编程还是有点陌生。感谢您的帮助。
最佳答案
Objective-C++ 不以这种方式互操作。 -(BOOL)LaunchApp:(CAtlString)exePath
在 Objective-C 类上声明了一个实例方法。该方法只能从 Objective-C(即 .m、.mm)文件中调用,并且如果方法签名包含 C++ 类型(就像它在此处所做的那样),那么它只能从 Objective-C++ (.mm) 中调用文件。此外,-(BOOL)LaunchApp:(CAtlString)exePath
是一个实例方法,您似乎在调用它,就好像它是 C++ 静态/类方法一样,这也不起作用。
如果你想包装你的 Objective-C 类,让直接的 C++ 消费者可以使用它,你必须这样做:
MyLaunchClass.h:
#if __cplusplus
#import <string>
#endif
@interface MyLaunchClass : NSObject
#if __cplusplus
- (BOOL)launchApp: (std::string)str;
#endif
@end
#if __cplusplus
struct WrappedMyLaunchClass
{
MyLaunchClass* mImpl;
WrappedMyLaunchClass() : mImpl([[MyLaunchClass alloc] init]) { };
~WrappedMyLaunchClass() { mImpl = nil; }; // Assuming ARC here. for non-ARC, [mImpl release]
bool LaunchApp(std::string str)
{
return !![mImpl launchApp:str];
}
};
#endif
MyLaunchClass.mm:
#import "MyLaunchClass.h"
#import <string>
@implementation MyLaunchClass
- (BOOL)launchApp: (std::string)str
{
NSLog(@"%s", str.c_str());
return YES;
}
@end
SomeOtherFile.cpp:
void someOtherFunction()
{
WrappedMyLaunchClass x;
x.LaunchApp("foobar");
}
总之,您高估了 C++ 和 Objective-C++ 的互操作性。您可以将 Objective-C++ 视为“具有 C++ 类型变量和调用 C++ 代码能力的 Objective-C”,但不是作为“声明 C++ 类型的替代语法” ”
Caveat Emptor!:这极大地简化了将 Objective-C 对象有意义地包装在 C++ 对象中所涉及的内容。 C++ 的按值/按引用语义与 Objective-C 的截然不同,如果 C++ 对象按值传递(即通过一个复制构造函数)等。我提供示例只是为了说明为什么您尝试的方法不起作用,而不是将 Objective-C 对象包装在 C++ 对象中的某种通用代码。
关于c++ - 从 .cpp 文件调用 .mm 函数的链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19007376/