【问题标题】:Calling function by name using dlsym in iOS在 iOS 中使用 dlsym 按名称调用函数
【发布时间】:2011-02-18 10:56:46
【问题描述】:

我不能在 iOS 中按名称调用函数吗?我有一个名为getstring 的C 函数。我这样称呼它:

void* handle = dlopen(NULL, RTLD_NOW);
if (handle)
{
fp func = dlsym(handle, "getstring");
if (!func)
    responseField.text = [NSString stringWithUTF8String:dlerror()];
else {
    char* tmpStr = func();
    responseField.text = [NSString stringWithUTF8String:tmpStr];        
}
}
else {
responseField.text = [NSString stringWithUTF8String:dlerror()];
}

执行此操作时,responseFiled.text 设置为 dlsym(...): symbol not found。这意味着 dlopen 有效,但 dlsym 无效。我使用nm 将符号转储到二进制文件中,并看到_getstring 存在。我检查了manualdlsym,它说我不应该在名称中添加下划线。无论如何添加它并不能解决问题。我究竟做错了什么?

我曾问过一个类似的问题here 关于在 Objective-C 中按名称调用函数,然后按照答案在 Mac 上成功尝试,所以这个问题似乎是 iOS 特有的。

【问题讨论】:

    标签: ios dlopen dlsym


    【解决方案1】:

    我认为问题在于 iOS 不支持 dlopen,即使您静态链接库也是如此。你应该能够使用

    dlsym(RTLD_SELF, "getstring");
    

    因为 RTLD_SELF 的意思是“开始查看调用 dlsym 的图像”。根据您使用 dlopen() 的方式,它应该可以完成同样的事情。

    【讨论】:

      【解决方案2】:

      实际上,我在与您类似的案例中也有过一些成功的经验。我使用dlsym(RTLD_MAIN_ONLY, "getstring") 来获取函数指针。

      请注意,您的 getstring 符号必须适合动态链接:可以使用

      进行检查
      nm -m <application>
      

      您的符号必须是external(而不是non-external)。

      我还不太确定确保符号标记为external的过程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-23
        • 1970-01-01
        • 2017-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多