我有一个JavaScriptCore框架的分支,在其中添加了自己的功能,该功能已导出。该框架编译才发现。在框架上运行nm显示该函数(JSContextCreateBacktrace_unsafe)确实已导出:

Leo-Natans-Wix-MPB:JavaScriptCore.framework lnatan$ nm -gU JavaScriptCore.framework/JavaScriptCore | grep JSContextCreateBacktrace
00000000004cb860 T _JSContextCreateBacktrace
00000000004cba10 T _JSContextCreateBacktrace_unsafe

但是,我无法使用CFBundleGetFunctionPointerForNamedlsym获得该函数的指针;都返回NULL。首先,我使用dlopen打开我的框架,然后尝试使用CFBundleCreateCFBundleGetFunctionPointerForName,但这也返回NULL。

是什么原因造成的?

更新

可疑的事情正在发生。我重命名了JSC函数之一,nm反映了这一点。但是,dlsym仍然能够找到具有原始名称而不是重命名的函数。

最佳答案

由于它高度依赖于您的特定环境和情况,因此很难进行跟踪,但是很有可能您正在遇到此问题,因为系统映像已经加载并且您没有更改框架的名称。

如果查看dyld/dyldAPIS.cpp:1458dlopen的源代码,您会注意到传递给dyld的上下文已使用matchByInstallName = true配置。然后将此上下文传递给load,该文件执行图像加载所需的各个阶段。有几个阶段值得注意:

dyld/dyld.cpp:2896中的

  • loadPhase2提取框架路径的结尾并在搜索路径
  • 中进行搜索
    dyld/dyld:2712中的
  • loadPhase5check遍历所有已加载的映像,并确定它们是否具有匹配的安装名称,如果存在,则返回该名称而不是加载新的图像。
  • 如果以前的任何步骤未加载/找到图像,则dyld/dyld:2601中的
  • loadPhase5load最终将加载该图像。 (值得注意的是,首先执行loadPhase5check,因为图像加载是一个两遍过程。)

  • 鉴于以上所有内容,我将尝试将您的框架重命名为JavaScriptCore.framework以外的名称。根据系统框架和框架的安装名称,我还建议更改安装名称。 (有很多博客文章和StackOverflow帖子记录了如何使用install_name_tool -id进行此操作。)

    关于ios - CFBundleGetFunctionPointerForName和dlsym为导出的函数返回NULL,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46148634/

    10-10 17:00