在Linux程序中嵌入Python

在Linux程序中嵌入Python,python,c++,linux,python-3.4,python-c-api,Python,C++,Linux,Python 3.4,Python C Api,我目前正试图在我的C++应用程序中嵌入Python,以给用户高级脚本的可能性。 到目前为止,我的程序在Windows上运行得很好,完全正常,现在我正尝试在GNU/Linux Debian 7上运行同样的程序,但这给我带来的麻烦比我预期的要多得多。 首先,我下载python.tar.gz并使用enable shared选项从源代码处编译它,以获得fPIC选项: ./configure-enable shared-prefix=/opt/python 生成和生成altinstall(&M) 然后,由

我目前正试图在我的C++应用程序中嵌入Python,以给用户高级脚本的可能性。 到目前为止,我的程序在Windows上运行得很好,完全正常,现在我正尝试在GNU/Linux Debian 7上运行同样的程序,但这给我带来的麻烦比我预期的要多得多。 首先,我下载python.tar.gz并使用enable shared选项从源代码处编译它,以获得fPIC选项: ./configure-enable shared-prefix=/opt/python 生成和生成altinstall(&M) 然后,由于pip:python3.4-m pip-install-numpy,我安装了numpy。简单

最后,我将安装复制到另一个位置是的,它应该部署在任何地方,确切地说是在我的主目录中,并将其命名为python_install。这本书似乎让我很痛苦

在代码方面,我调用Py_Initialize,它运行良好。以下是我迄今为止所做的工作:

#include "Python.h"

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "numpy/arrayobject.h"

#include <iostream>

int InitNumpy()
{
    import_array();
}

int main()
{
    std::string python_home = "/home/xxxx/dev/test-python/python_install";
    setenv("PYTHONHOME", python_home.c_str(),1 );

    Py_Initialize();

    std::cout << "Importing Numpy... ";
    int cr = InitNumpy();
    std::cout << cr << std::endl;

    return 0;
}
ImportError:numpy.core.multiarray导入失败 我认为错误很明显,Python找不到任何库,包括numpy。但我已经尝试了从设置PYTHONPATH到使用-Wl,-rpath设置其他目录的所有方法。。。。即使是PySys_SetPath。。。在Windows上工作的东西在Linux上失败了。 任何想法都欢迎!谢谢

编辑:以下是我使用的makefile:

CC=g++
CFLAGS= -Ipython_install/include/python3.4m -Ipython_install/lib/python3.4/site-packages/numpy/core/include -Wno-unused-result  -DNDEBUG -g -fwrapv -O3 -Wall
#Wrong
#LDFLAGS= -Lpython_install/lib/python3.4/config-3.4m -lpython3.4m -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-rpath,\$${ORIGIN}/python_install/lib
#Right
LDFLAGS= -Lpython_install/lib/ -lpython3.4m -lpthread -ldl  -lutil -lm  -Xlinker -export-dynamic -Wl,-rpath,\$${ORIGIN}/python_install/lib
EXEC=test-python

all: $(EXEC)

test-python: test-python.o
    $(CC) -o $@ $^ $(LDFLAGS)

%.o: %.cpp
    $(CC) -o $@ -c $< $(CFLAGS)

.PHONY: clean mrproper

clean:
    rm -rf *.o

mrproper: clean
    rm -rf $(EXEC)

选项直接来自python3.4m-config可执行文件…

您说python找不到任何库,您是否尝试过启动python并导入它们?如果直接在python中导入存在问题,则必须重新检查PYTHOPATH是否正确,或者您安装的文件没有安装要执行的权限设置。我已经经历过两次了

另外,您是否从?中查看了在类unix系统上编译的提示

找到合适的标志传递给您的应用程序并不一定很简单 编译器和链接器,以便将Python解释器嵌入 您的应用程序,特别是因为Python需要加载库 模块实现为C动态扩展名。因此文件链接 它

要查找所需的编译器和链接器标志,可以执行 pythonX.Y-config脚本,作为 安装过程也可以使用python3配置脚本

如何编译代码

编辑

我已经尽力重现你的错误,但在我的机器上做不到。我所知道的最远的情况是,我认为你对错误的分析是错误的

我认为错误很明显,Python找不到任何库 包括努比

拥有import_数组的原因是检查是否有numpy,以及您拥有的numpy版本是否与安装的python版本匹配。在源代码中,它被定义为宏,即py2的np:

#if PY_VERSION_HEX >= 0x03000000
#define NUMPY_IMPORT_ARRAY_RETVAL NULL
#else
#define NUMPY_IMPORT_ARRAY_RETVAL
#endif

#define import_array() {if (_import_array() < 0) {PyErr_Print();
PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to
import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
由于这就是您看到的错误,我有理由怀疑您的pip为您的python版本安装了错误的numpy。但是,根据makefile,python3.4文件夹中有一个numpy,如果没有,它将抛出一个错误,没有这样的文件或目录。另外,你说你甚至不得不使用LD_LIBRARY_PATH not recommended btw来启动带有numpy的python,这意味着当前为你的python定义的任何路径都没有正确地指向numpy,包括你在编译的python中的site packages文件夹,默认情况下,它会被搜索

我怀疑您在默认情况下安装了一个预先存在的python,并且您的系统范围的环境路径设置为它。但考虑到你显式链接了python3文件夹中的numpy,然后设置了env PYTHONHOME,这真是一个奇怪的说法


很抱歉,我不能提供更多的帮助,但是如果不从头开始构建python,我就无法重现这个问题,目前也不在debian上。祝你好运,随时通知我?

简短的回答是:不要在Python上静态链接。所有Python模块都在Lypython 3.4.So上动态链接,因此C++程序也必须这样做。 总结一下Python嵌入:

在Python cf修改的Makefile上动态链接。使用rpath定位python.so。 在C++代码中,将Python Hoad环境变量设置为Python安装或使用pyth-TyPythOnHoad函数。 调用Py_初始化; 如果要导入自定义模块,请将模块路径添加到Python路径

PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString(sys_path.toUtf8().data()));

我编辑了我的第一篇文章以显示完整的代码。如果我用LD_LIBRARY_PATH启动Python可执行文件本身来帮助他找到。另一方面,当我从C++代码调用IMPILE数组时,总是会有导入错误!在我的非常小的示例中,它最终使用rpath和strace工作。但我无法在我的大项目中转移这一点。我必须找出原因。我会随时通知社区@poukill我尽了最大努力,但无法让python像你一样运行,即使我取消设置路径链接似乎对我有效
E即使我移动我的程序。这是个好消息。但是,如果我使用完全相同的方法在其他地方安装另一个Python,但没有numpy,则主安装将不再工作,并且我得到我的ImportError:numpy.core.multiarray无法导入回。。。如果我在最后一次Python安装时安装numpy,那么这两个应用程序都可以工作。总结:1-使用test-Python.cpp安装Python和numpy。编译并启动。工作2-移动到另一个文件夹。还在工作。3-在旧文件夹上重新安装Python。弄坏了新的。看起来我至少在附近。希望我能帮点忙。但这对您来说是个坏消息,这意味着它不能作为一个独立的组件部署。不在“干净安装”或至少在virtualenv之外。建筑是一种过度消耗。此外,我正在浏览boost库的安装,试图找到一个解决方案的线索,你可能会发现它也很有用。我无法重现你的问题。按照你给出的所有步骤进行操作,效果很好。我所能想到的是,numpy实际上并不存在于您提供的python主页下。您是否尝试过运行安装的交互式解释器并导入numpy以确保未设置PYTHONPATH?是的,我也是。长话短说:我第一次安装了Python,并将安装复制到我的小项目中。我不知道为什么,但numpy指的是第一次安装斯特拉斯给了我线索。我删除了第一次安装,现在它可以工作了。。。但我希望我将来能够很好地与其他Python安装集成,否则一些用户肯定会抱怨……我发现pip是硬编码的,使用原始安装路径来查找Python可执行文件。也就是说,它不会尝试使用与共享目录的python可执行文件。可能是pip的安装路径也是硬编码的——这意味着您将无法移动python安装。@Dunes:是的,您可能是对的。当我尝试在移动的文件夹上使用pip时,我得到一个/usr/bin/ld:not find-lpython3.4m。真正的问题是:我应该通过apt get在.deb存档中部署我的应用程序和python包装器。。。所以我可能会在某个地方强制安装python。我不得不考虑一下。@Dunes我终于找到了我的问题所在。生成文件不正确。我在libpython.a上进行了静态链接,但是像numpy这样的附加安装使用了libpython3.4.so,它似乎引发了一些我不理解的奇怪冲突。好吧,现在我在两边使用动态链接共享对象,它工作得很好。5天的麻烦,一个奇怪的选择……你介意添加一个例子,你如何设置Python Head在C++代码中?我认为使用PythStPythOnHoad做同样的事情,应该使用。查阅