我目前正在尝试在我的C ++应用程序中嵌入Python,以便为用户提供高级脚本编写的可能性。
到目前为止,我的程序在Windows上工作得很好(它完全正常工作),现在我正在尝试在GNU / Linux(现在的Debian 7)上做同样的事情,但这给我带来的麻烦比我预期的要多得多。
首先,我下载python.tar.gz并使用enable-shared选项从源代码编译它以获取fPIC选项:
./configure --enable-shared --prefix = / opt / python
制造&&使altinstall
然后,由于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可执行文件...
答案 0 :(得分:3)
简短的回答是:不要在Python上静态链接。所有Python模块都在libpython3.4.so上链接动态,因此C ++程序必须这样做。 总结Python嵌入:
PYTHONHOME
环境变量设置为Python安装或使用Py_SetPythonHome()
函数。Py_Initialize();
如果要导入自定义模块,请将模块路径添加到Python路径。
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString(sys_path.toUtf8().data()));
答案 1 :(得分:1)
你说“python找不到任何库”,你试过启动python并导入它们吗?如果直接在python中导入是一个问题,那么您将不得不重新检查PYTHOPATH
是否正确,或者您安装的文件是否未安装以及要执行的权限设置。 (我已经两次了)。
另外,您是否已从manual?查看了在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,包括你编译的python中的site-packages
文件夹(默认搜索)。
我怀疑您默认安装了预先存在的python,并且系统范围的环境路径已设置为它。但考虑到你明确链接python3文件夹中的numpy AND 你setenv
PYTHONHOME
,这是一个非常奇怪的陈述。
对不起,我无法提供更多的帮助,但如果没有从头开始实际进行python构建(目前还没有在debian上),我无法重现这个问题。祝你好运,让我发布?