架构arm64的未定义符号.对ObjC++文件进行C调用

Undefined symbols for architecture arm64. Make C calls into ObjC++ file?

本文关键字:文件 调用 ObjC++ arm64 未定义 符号 架构      更新时间:2023-10-16

我收到这个Apple Mach-O链接器错误:

Undefined symbols for architecture arm64:
  "_TestFunction", referenced from:
      -[ViewController viewDidLoad] in ViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

以下是重现错误所需的所有步骤:

  1. 我创建了一个新的单视图通用Objective C项目(Xcode版本6.0.1(6A317))
  2. 然后我创建了一个名为TestClass的新ObjectiveC文件
  3. 将TestClass.m更改为TestClass.mm
  4. 在我的.h中添加"void TestFunction();"
  5. 在我的.mm中添加"void TestFunction(){}"
  6. TestClass.h导入我的ViewController.m,并尝试从我的viewDidLoad调用TestFunction()

我正在做一些核心音频工作,需要在MIDI回调中进行一些C++调用,所以我不能进行任何ObjectiveC方法调用,因为它们会阻塞音频线程。

也许Xcode将TestFunction()视为C++调用,所以不会从纯ObjectiveC类中生成它?有没有办法告诉Xcode它是一个C函数?

您需要将您的c++函数标记为extern "C"
之后,目标c代码可以链接到该函数。

你的TestClass.h应该看起来像这个

#if defined __cplusplus
extern "C" {
#endif
void TestFunction();
#if defined __cplusplus
};
#endif  

extern"C"使C++中的函数名具有"C"链接(编译器不会损坏名称),以便客户端C代码可以使用仅包含函数声明的"C"兼容头文件链接到(即使用)您的函数。函数定义包含在二进制格式中(由C++编译器编译),然后客户端"C"链接器将使用"C"名称链接到该格式。

由于C++有函数名重载,而C没有,因此C++编译器不能仅将函数名用作链接到的唯一id,因此它会通过添加有关参数的信息来破坏名称。C编译器不需要篡改名称,因为您不能重载C中的函数名称。当您声明函数在C++中具有外部"C"链接时,C++编译器不会向用于链接的名称添加参数/参数类型信息。