我正在构建一个要嵌入 Python 的 Mac OS X 应用程序。我的应用程序在技术上是一个包(即它的主要可执行文件是 MH_BUNDLE);它是另一个应用程序的插件。我希望它静态嵌入 Python,但希望能够动态加载扩展。
我做了以下事情:我包含了整个库(-force_load path/to/libpython2.7.a
),还重新导出了所有 Python 符号(-exported_symbol_list path/to/list
),并添加了 -u _PyMac_Error
,这是我使用 this linking advice 得到的. bundle 本身加载正常,所有内部 Python 代码似乎都可以工作,但是当它尝试导入动态库 (time.so
) 时失败并显示以下消息:
Traceback (most recent call last):
...
ImportError: dlopen(/<stripped>/time.so, 2): Symbol not found: _PyExc_OverflowError
Referenced from: /<stripped>/time.so
Expected in: dynamic lookup
这个符号是 Python API 的一部分,它一定已经在我的包中了。我可以检查一下:
nm -g Build/Debug/pyfm | grep _PyExc_OverflowError
00172884 D _PyExc_OverflowError
0019cde0 D _PyExc_OverflowError
(列出两次是因为我有两种架构,i386和ppc)。
time.so
没有引用任何东西,据我所知,这是设计使然:
otool -L "/<stripped>/time.so"
/<stripped>/time.so (architecture ppc):
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11)
/<stripped>/time.so (architecture i386):
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.11)
我的问题似乎类似于 this ,但情况恰恰相反:我静态链接 Python,而另一张海报动态链接它(我们的平台也不同)。对他来说,静态链接解决了这个问题。
为什么找不到符号?
更新。我怀疑这是因为主应用程序使用 RTLD_LOCAL
加载了它的插件(因此我的包)。
最佳答案
我做的“更新”表明它是正确的:主插件包在本地加载(RTLD_LOCAL
),所以没有人可以在那里看到任何符号,除非使用明确的dlopen
后跟 dlsym
。
如果是 Linux,我可以通过 dlopen
使用 RTLD_GLOBAL
标志将它提升到全局命名空间,但在 Mac OS X 下这不起作用.但是 Mac OS X 很好地把东西打包成包,所以我只是制作了一个动态库并将其放入插件包目录中。该库作为 RTLD_GLOBAL
自动加载,并且所有 Python 符号都可用。
关于python - 在 Mac OS X 上静态嵌入 Python 时动态符号查找失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4193539/