从文件调用 .mm 函数时链接器出错.cpp
Linker error calling .mm function from .cpp file
我已经在我当前的 Xcode 4.6 项目中添加了一个 obj-c 类(.mm 和 2 个标头(。一个头文件具有要调用 obj-c 类的原型,另一个头文件定义 .mm 类。这是它的样子。
我的界面.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 文件添加到目标,并将标头位置添加到构建设置中的标头搜索路径。
当我将头文件包含在我的.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
其他文件.cpp:
void someOtherFunction()
{
WrappedMyLaunchClass x;
x.LaunchApp("foobar");
}
总之,你高估了C++和Objective-C++的互操作性。 你可以将 Objective-C++ 视为"Objective-C,增加了具有C++类型变量和调用C++代码的能力",但不是"声明C++类型的替代语法"。
警告Emptor!:这大大简化了将Objective-C对象有意义地包装在C++对象中所涉及的内容。 C++的按值/按引用语义与Objective-C的语义截然不同,如果C++对象通过值传递(即通过复制构造函数(等,像这样的天真实现会遇到各种问题。我提供这个例子只是为了说明为什么你尝试的东西不起作用,而不是作为某种通用代码,将Objective-C对象包装在C++对象中。
- 读取文件的最后一行并输入到链接列表时出错
- C++ 创建包含链表和字符串的对象的链接列表时出错
- 在发布模式下启动使用库的静态链接编译的应用程序时出错
- 编译时出错 - 链接.cpp和头文件
- 将 boost 与 Visual Studio 和 vcpkg 链接时出错
- 获取链接 创建flyweight_pattern时出错
- 从Qt5链接MySQL时出错
- 迭代器关系运算符出错(带单独链接和迭代器的自定义哈希表)
- 与 glfw3 链接时出错
- GNU 链接器:如果头文件中的指针被声明为 NULL 和/或 extern,则出错
- 可能的 GCC 链接器错误会导致将弱符号和局部符号链接在一起时出错
- 使用提升库和 clion 链接时出错
- 在 Fedora 27 中构建 GLFW 时链接期间出错
- 将 CLANG 构建的可执行文件与 G++-v6 构建的 Boost 库链接时出错
- 链接 gtest 项目时出错
- 链接webrtc本机时出错,因为未定义对具有std::string的方法的引用
- wxwidget 3.1.2 代码块 17.04 在链接步骤中出错
- 链接Firebase C (分析)库时出错
- 在Windows上使用GCC的链接时间优化构建wxWidgets DLL时出错
- 链接外部变量 c++ 时出错