0

我的目标是用 boost python 创建一个 python 扩展模块。问题是当共享库中的代码使用 dlopen 访问同一库中的符号时,它会失败(详情如下)。似乎模块中的符号没有加载到python进程的符号表中

我在共享库 myTest.so 中有以下代码

// File 1
extern "C" void target_func() {
    std::cout << "Works!" << std::endl;
}

// File 2
typedef void (*Func) ();
void run() {
    void *handle = dlopen(0, RTLD_NOW | RTLD_GLOBAL)
    Func *method = (Func *)dlsym(handle, "target_func");
    // check if method is NULL and fail
}

它包含在一个 boost python 模块中,如图所示 -

BOOST_PYTHON_MODULE(myTest) {
    def("run", run);
}

当我导入python模块并执行时,上面的代码失败

import myTest
myTest.run()

undefined symbol: target_func

但是,当我将myTest.so与调用 run 的主函数链接时没有问题,如下所示

int main(int argc, char **argv) {
    run();
}

Output: Works!
4

1 回答 1

5

默认情况下,解释器不会以跨扩展共享符号的方式加载扩展。这可以通过设置dlopen()解释器使用的标志来修改sys.setdlopenflags()。该文档指出:

要跨扩展模块共享符号,请调用 as sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)


这是使用默认设置加载扩展的解释器:

>>> import myTest
>>> myTest.run()
/usr/bin/python: undefined symbol: target_func

修改解释器的dlopen()标志后会成功:

>>> import sys
>>> import dl
>>> sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
>>> import myTest
>>> myTest.run()
Works!
于 2013-10-29T16:45:59.443 回答