gpt4 book ai didi

python - 在 Python 中加载 C 库会打开另一个 C 库 - 未解析的共享符号

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:04:00 27 4
gpt4 key购买 nike

我有一个具有多种功能的商业 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 associated dlsym() 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 as RTLD_GLOBAL.

ctypes.DEFAULT_MODE
The default mode which is used to load shared libraries. On OSX 10.3, this is RTLD_GLOBAL, otherwise it is the same as RTLD_LOCAL.

从文档中可以看出,您所处的系统中 DEFAULT_MODERTLD_LOCAL 相同,这与 RTLD_GLOBAL 相反。

关于python - 在 Python 中加载 C 库会打开另一个 C 库 - 未解析的共享符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51544050/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com