使用 Numpy 将 Python 库静态链接到 C (C++)

Posted

技术标签:

【中文标题】使用 Numpy 将 Python 库静态链接到 C (C++)【英文标题】:Static linking Python library to C (C++) with Numpy 【发布时间】:2017-10-27 22:22:08 【问题描述】:

我正在开发一个嵌入了 python 的 C++ 库。我想做的是静态链接Python库,这样当我切换到生产服务器时就不会出现配置问题。到目前为止,我能够静态链接libpython3.5m.a(尽管我必须从源代码构建Python,因为看起来打包的库不是用-fPIC 标志编译的)。但是,我遇到了一个问题,似乎没有 Numpy:当我运行使用我的库的应用程序时,它提示我一个错误:

ImportError: numpy.core.multiarray failed to import

这个错误是由import_array1() 宏引起的,那个(AFAIK)用于将numpy 例程导入C++。我尝试链接libnpymath.alibnpysort.a,我在 numpy 构建目录中找到了它们,但无济于事。您是否碰巧知道,如果这种静态链接是可能的以及如何做到这一点?我想这应该是可能的,因为 numpy 是用 C 编写的......

【问题讨论】:

对于您问题的第一部分,为什么您不使用 dll 文件?!用你自己的类制作你自己的 dll,你可以调用 dll 文件并将它们的函数与 ctypes 模块一起使用......你也可以使用 sys.path.append('./yourpath/yourpath') 函数与 sys 模块进行静态链接,然后导入您自己的模块... @DRPK 问题出在其他库上(我在 linux 上,所以使用 .so 而不是 .dll)。我在ubuntu16上开发,服务器是debian stretch,它有2个不同版本的libc.so(C++库)。由于我不能用一个编译并使用另一个,我想静态链接。同样的情况也发生在蟒蛇身上。我有 3.5,有 3.4... 【参考方案1】:

我想做的是静态链接Python库,这样当我切换到生产服务器时就不会出现配置问题。

这只是 Python 核心,它将排除所有 Python 库。您仍然需要提供所有 Python 代码。

...因为 numpy 是用 C 编写的...

这是不正确的。 NumPy 大约一半用 C 语言编写,一半用 Python 编写。看起来 C 部分是这里没有加载的部分,因为 numpy.core.multiarray 是用 C 编写的,您通常不会自己导入它,它通常会由 NumPy 的 Python 部分导入。

C 代码中的链接无论如何是不够的,您需要加载初始化 C 代码导出的关联 Python 模块。如果没有静态链接,Python 只会在正确的位置找到 multiarray.so 文件并加载它。当您静态构建 Python 时,您通常会编辑 Modules/Setup.local 文件,其中包含您希望静态编译到 Python 中的模块。但是,这并不是为与 NumPy 等任意第三方模块一起工作而设计的。见:Compile the Python interpreter statically?


老实说,如果您只是想确保在开发和生产系统上都运行相同版本的 Python,那么有 非常 更简单的方法可以做到这一点,例如 virtualenv。 CPython 根本不是为静态链接而设计的。

【讨论】:

以上是关于使用 Numpy 将 Python 库静态链接到 C (C++)的主要内容,如果未能解决你的问题,请参考以下文章

我无法使用 Visual Studio 将 python.dll 构建为静态库 (/MTd)

将静态本机库链接到托管 C++ 项目会在

将静态库与静态库链接

如何使用boost.python中的-fPIC编译静态库

静态库,链接到共享库

将静态库链接到共享库(例如openmp)是一个好主意