c++ - 动态链接和 Python SWIG (C++) 在 C++ 中工作在 python 中失败

标签 c++ python swig dynamic-linking

我有一个库,我使用 SWIG 创建了一个 python 包装器。该库本身接受用户提供的函数,这些函数位于动态链接的 .so 文件中。目前,我正在处理我自己创建的一个,并设法在 C++ 中使动态链接正常工作。当我尝试在 python 中运行它时,出现 undefined symbol 错误。这些符号不存在于提供的 .so 文件中,但存在于主程序中(本质上它们是允许提供的模块从主程序访问数据的函数)。

我在 C++ 中运行一个简短的测试程序没有遇到任何错误,但是使用这个包装器(之前工作过)在 python 中运行一个简短的测试程序失败了。我想不出为什么它在 C++ 中失败而不是在 python 中失败的解释。让我稍微担心的是 C++ 无法正常工作但没有告诉我,并且 python 正在拾取 C++ 没有的错误。然而 C++ 返回的结果是准确的,因此这似乎不太可能。

有什么想法这是可能的,因此我该如何解决它?

谢谢。

更新: 我已将此代码添加到程序顶部:

import dl
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)

这消除了运行时错误,但不幸的是,导致出现第二个问题(仍然是由于链接)。从作为主程序一部分的动态链接库中调用的函数未返回正确的值。它们返回 0。更重要的是,很明显它们根本没有被运行。问题是实际运行的是什么,为什么它与 C++ 不同,以及如何解决这个问题?

再次感谢。

更新-可能更清晰的解释 Python 导入一个模块,这是我的 C++ 库,已被 SWIG 封装。此 C++ 库使用 dlopen 和 dlsym 从用户提供的 .so 文件中获取函数。用户提供了对 C++ 库中的函数的文件调用来完成其工作。从 .so 文件到 C++ 库的函数调用是失败的部分,即它们无法调用该函数,只是返回 0。但是,只有当测试代码是用 python 编写时,才会出现这种失败。使用该库的 C++ 测试代码工作正常。

最佳答案

解决方案是确保 python 在全局范围内预加载 C++ 主库。 这不是一个非常优雅的解决方案,我也不想这样做,但它暂时可以工作。

经过一番探索后 here并认识到每次启动终端时都必须设置的 LD_LIBRARY_PATH 环境变量,以便它找到已 SWIGed 的主 C++ 库,我注意到 LD_PRELOAD 环境变量。将其设置为主 C++ 库的文件名后,程序即可运行。

我怀疑这是因为它“可用于选择性地覆盖其他共享库中的函数”。

如果有人能提出比设置环境变量更好的答案,那就太棒了,因为我不确定它的可移植性如何。

编辑:最初的问题是用户提供的库正在查找的函数不在全局范围内。为了解决这个问题,只需使用 python 的“dl.open”打开主库的 .so 文件,使用 dl.RTLD_NOW 和 dl.RTLD_GLOBAL。

成功!

关于c++ - 动态链接和 Python SWIG (C++) 在 C++ 中工作在 python 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3396966/

相关文章:

python - 将数据结构转换为csv

java - SWIG Java - 将 unsigned char[] 包装在 byte[] 中

c++ - 如何使用 SWIG 为 C++ std::vector 生成 Lua 迭代器?

python - 减少Python字典中带有关键字参数的函数列表

C++11 std::shared_ptr 工作正常,但 boost::shared_ptr 崩溃,这可能是什么原因?

c++ - 在容器元素上应用函数需要更好的名称

c++ - 表达式未计算为常量- c++

python - 获取当前页面加载时间设置 Selenium Python

python - 带有 SWIG 的 Python 中 C++ 类的奇怪行为

c++ - 为什么 GCC 生成的代码会从堆栈中读取垃圾?