- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个具有多种功能的商业 C 库 (a.so)。当您调用 a.open() 函数时,它会动态地对另一个库执行 dlopen() 调用。如果调用 a.open('b'),它将打开 b.so。如果调用 a.open('c'),它将打开 c.so。
问题是 a.so 和 b.so 共享一个在 a.so 中定义的全局变量,但被 b.so(和 c.so 等)引用。我能够使用 ctypes 在 python 中正确加载 a.so 并查看 Python 中的所有符号。但是,当我调用 a.open('b') 时,它会尝试加载 b.so 但返回 undefined symbol 。
//a.c -source for a.so library
int aglobal = 0;
void open(char* lib)
{ dlopen(lib); }
//b.c - source for b.so library
extern int aglobal;
这是我要加载的 python 代码:
from ctypes import cdll
p = ctypes.CDLL('a.so')
p.open('b')
返回错误代码:undefined symbol: aglobal
一些其他注意事项:
文件与 -fPIC -rdynamic -shared 链接
当我编写一个与 python 程序功能相同的 C 程序时,没有问题。
我也尝试过用 swig 包装库,以及许多其他东西、构建选项等,但结果相同。
Python 是否以不同方式绑定(bind)符号?
最佳答案
您需要使用 RTLD_GLOBAL
当你加载 a.so
时。
The object's symbols shall be made available for the relocation processing of any other object. In addition, symbol lookup using
dlopen(0, mode)
and an associateddlsym()
allows objects loaded with this mode to be searched.
Linux man page更直接一点:
The symbols defined by this shared object will be made available for symbol resolution of subsequently loaded shared objects.
python documentation描述了选项的存在,但没有描述它的作用。
New in version 2.6: The use_last_error and use_errno optional parameters were added.
ctypes.RTLD_GLOBAL
Flag to use as mode parameter. On platforms where this flag is not available, it is defined as the integer zero.
ctypes.RTLD_LOCAL
Flag to use as mode parameter. On platforms where this is not available, it is the same asRTLD_GLOBAL
.
ctypes.DEFAULT_MODE
The default mode which is used to load shared libraries. On OSX 10.3, this isRTLD_GLOBAL
, otherwise it is the same asRTLD_LOCAL
.
从文档中可以看出,您所处的系统中 DEFAULT_MODE
与 RTLD_LOCAL
相同,这与 RTLD_GLOBAL
相反。
关于python - 在 Python 中加载 C 库会打开另一个 C 库 - 未解析的共享符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51544050/
我是一名优秀的程序员,十分优秀!