You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Swift项目引入C++ dylib遭遇未定义符号问题求助

解决Swift调用C++ dylib时的未定义符号问题

我来帮你一步步排查这个问题,出现未定义符号大概率是C++的名字修饰或者链接配置没做好,咱们逐个解决:

1. 修复C++函数的名字修饰问题

C++编译器会对函数名做名字修饰(Name Mangling),这会导致dylib里的函数名和你头文件声明的addNumber不一致,自然会被Swift判定为未定义符号。你需要用extern "C"包裹暴露的函数,强制编译器用C风格的命名规则:

修改你的C++ dylib代码:

extern "C" {
__attribute__((visibility("default"))) int addNumber(int number) {
    return number; // 这里可以写你实际的实现逻辑
}
}

2. 确保Swift项目正确链接dylib文件

你只导入了头文件和module.map,但Swift项目并没有实际关联到编译好的dylib文件,这是最容易遗漏的步骤:

  • 把编译好的libMyLib.dylib(你的dylib实际文件名)拖到Swift项目的Frameworks, Libraries, and Embedded Content区域(在项目目标的General标签页下)
  • 或者在项目目标的Build Settings里:
    • 找到Library Search Paths,添加dylib所在的目录路径
    • 找到Other Linker Flags,添加-lMyLib(注意这里用库名,去掉lib前缀和.dylib后缀)

3. 完善头文件的兼容性

为了让头文件同时兼容C和C++编译器,建议给头文件加上extern "C"的条件编译包裹:

#ifndef mylib_h
#define mylib_h

#ifdef __cplusplus
extern "C" {
#endif

int addNumber(int number);

#ifdef __cplusplus
}
#endif

#endif

4. 验证module.map和导入路径

  • 确保module.map的路径设置正确:在Swift项目的Build Settings里找到Import Paths,添加的是包含module.map的目录,而不是module.map文件本身
  • 确认module.map内容无误:
module MyLib {
    header "myLib.h"
    export *
}

5. 检查dylib的编译参数

如果是手动编译dylib,要确保用-dynamiclib参数生成动态库,比如:

clang -dynamiclib -o libMyLib.dylib myLib.cpp

如果是用Xcode编译dylib项目,要确认项目的Mach-O Type设置为Dynamic Library,且你的函数已经通过__attribute__((visibility("default")))显式暴露。

做完这些调整后,重新编译Swift项目,应该就能正常调用addNumber函数了。

内容的提问来源于stack exchange,提问作者Shai

火山引擎 最新活动