在Linux程序中embeddedPython

我目前正在尝试在我的C ++应用程序中embeddedPython,以便为用户提供高级脚本function。 到目前为止,我的程序在Windows上工作良好(现在正在运行),现在我正在尝试在GNU / Linux(现在是Debian 7)上做同样的事情,但这给我带来了比预期更多的麻烦。 首先,我下载python.tar.gz并使用enable-shared选项从源代码编译,以获得fPIC选项:
./configure –enable-shared –prefix = / opt / python
make && make altinstall
然后,我安装numpy感谢pip: python3.4 -m pip install 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上失败。 任何想法都会受到欢迎! 谢谢。

编辑:这是我使用(纠正)的生成文件:

 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模块都在libpython3.4.so上动态链接,所以C ++程序也必须这样做。 总结Python嵌入:

  1. 在Python上动态链接(参考纠正的Makefile)。 使用rpath来查找python .so。
  2. 在C ++代码中,将PYTHONHOME环境变量设置为Python安装
  3. 调用Py_Initialize();
  4. 如果要导入自定义模块,请将模块路径添加到Python路径。

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

你说“蟒蛇无法找到任何库”,你有没有尝试启动Python并导入它们? 如果这是一个直接在Python中导入的问题,你将不得不重新检查PYTHOPATH是否正确,或者你的安装文件没有安装权限设置来执行。 (我曾经发生过两次)。

另外,你是否检查过在手册上编译unix类似系统的技巧?

为了将Python解释器嵌入到您的应用程序中,找到正确的标记传递给您的编译器(和链接器)并不是一件简单的事,特别是因为Python需要加载作为C动态扩展(.so文件)实现的库模块它。

要找出所需的编译器和链接器标志,可以执行作为安装过程的一部分生成的pythonX.Y-config脚本(python3-config脚本也可用)

你如何编译你的代码?

编辑

我尽了最大的努力来重现你的错误,但不能在我的机器上完成。 我得到的最远的是我认为你对错误的分析是错误的。

我认为这个错误很明显,Python找不到任何包含numpy的库。

有一个import_array()的原因是检查是否有一个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,如果没有,它会抛出一个错误No such file or directory 。 另外你说你甚至不得不使用LD_LIBRARY_PATH推荐btw)以numpy启动python,这只是意味着numpy实际上并没有被当前为你的python定义的任何路径正确指向,包括site-packages文件夹在你编译的python(默认情况下是通过搜索)。

我怀疑你有一个预先安装的默认python,并且你的系统环境路径被设置为它。 但是这是一个非常奇怪的说法,考虑到你明确地链接了python3文件夹中的numpy 你的setenv PYTHONHOME

对不起,我不能有更多的帮助,但我不能重现这个问题,实际上从头开始(也不是目前debian上)的python构建。 祝你好运,让我贴?