You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何iOS中无法用dlsym获取函数指针,Android却正常工作?

iOS下dlsym获取函数指针失败的解决方法

问题原因分析

  1. 调用约定不兼容:你在dylib源码中使用了Windows平台专属的__stdcall调用约定,iOS/macOS不支持该约定,编译器会对符号做异常修饰,导致dlsym无法匹配到正确符号。
  2. 导出符号的方式错误:__declspec(dllexport)是Windows平台的符号导出语法,在iOS/macOS环境下不生效,导致函数符号未被正确导出。

修正步骤

1. 修改dylib源码,适配iOS平台

将libSum.dylib的源码改为以下形式,使用苹果平台的标准符号导出规则,移除Windows专属语法:

extern "C" {
__attribute__((visibility("default")))
int sum(int x, int y) {
    return x + y;
}
}
  • extern "C":确保函数符号以C语言规则生成,避免C++的名字修饰干扰。
  • __attribute__((visibility("default"))):显式标记该函数为对外可见的导出符号,这是iOS/macOS平台导出动态库符号的标准方式。

2. 验证符号导出

重新编译dylib后,用命令行工具确认符号是否正确导出:

nm -g libSum.dylib

正常情况下会输出类似0000000000000f40 T _sum的结果,其中_sum就是可被dlsym识别的符号名。

3. 修正iOS端调用代码细节

  • 用标准宏定义替代硬编码数字:将dlopen的第二个参数从2改为RTLD_NOW,提升代码可读性和兼容性。
  • 添加错误日志:调用dlerror()获取dlsym失败的具体原因,便于排查问题。
  • 确保库路径正确:优先通过Bundle获取库的绝对路径,避免沙盒路径问题。

修正后的iOS代码示例:

NSString *libPath = [[NSBundle mainBundle] pathForResource:@"libSum" ofType:@"dylib"];
const char *func_name = "_sum";

void *libHandle = dlopen([libPath UTF8String], RTLD_NOW);
if (libHandle != NULL) {
    int (*sum)(int, int) = (int (*)(int, int))dlsym(libHandle, func_name);
    if (sum != NULL) {
        NSLog(@"%d", sum(5, 6));
    } else {
        const char *errMsg = dlerror();
        NSLog(@"dlsym failed: %s", errMsg);
    }
    dlclose(libHandle); // 使用完记得关闭库句柄
} else {
    const char *errMsg = dlerror();
    NSLog(@"dlopen failed: %s", errMsg);
}

4. 确保动态库正确嵌入App

在Xcode项目中,将libSum.dylib添加到Target -> General -> Embedded Binaries中,确保库被正确打包到App沙盒内,否则dlopen会找不到库文件。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:30:38