折腾了好久,终于弄出来了!不容易呀!
在这个过程中我遇到的坑最要有两个。
1、LIB和INCLUDE的路径配置。
2、没有设置python module路径,导致无法调用模型。
最后的最后,得出经验-->解决方法还是官网可靠!
总结出现的问题:1、如果,INCLUDE路径配置错误,则会出现无法include头文件Python.h
2、如果,LIB路径配置错误,则会出现无法调用python方法。(T_T)
3、如果,python module路径没正确配置或者没设置,将会出现无法调用module.
解决方案:1、参照官网的文档:
It is not necessarily trivial to find the right flags to pass to your compiler (and linker) in order to embed the Python interpreter into your application, particularly because Python needs to load library modules implemented as C dynamic extensions (.so files) linked against it.
To find out the required compiler and linker flags, you can execute the pythonX.Y-config script which is generated as part of the installation process (a python-config script may also be available). This script has several options, of which the following will be directly useful to you:
pythonX.Y-config –cflags will give you the recommended flags when compiling:
$ /opt/bin/python2.7-config --cflags
-I/opt/include/python2.7 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
pythonX.Y-config –ldflags will give you the recommended flags when linking:
$ /opt/bin/python2.7-config --ldflags
-L/opt/lib/python2.7/config -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic
如果,到这里你不成功的话。官网有个Note!自己去看吧。
Note
To avoid confusion between several Python installations (and especially between the system Python and your own compiled Python), it is recommended that you use the absolute path to pythonX.Y-config, as in the above example.
QT下的配置:
INCLUDEPATH += /usr/include/python2.7\
/usr/include/x86_64-linux-gnu/python2.7\
-fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
LIBS += -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpython2.7\
-lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
给出测试代码:
C++:
#include
#include
using namespace std;
int main()
{
Py_Initialize(); // 初始化
// 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性
//string path = "~/add";
string chdir_cmd = string("sys.path.append(\'/home/zsj/QT/helloworld\')");
const char* cstr_cmd = chdir_cmd.c_str();
cout << "path: " << cstr_cmd << endl;
PyRun_SimpleString("import sys");
PyRun_SimpleString(cstr_cmd);
// 加载模块
PyObject* moduleName = PyString_FromString("ab"); //模块名,不是文件名
PyObject* pModule = PyImport_Import(moduleName);
PyErr_Print();
if (!pModule) // 加载模块失败
{
cout << "[ERROR] Python get module failed." << endl;
return 0;
}
cout << "[INFO] Python get module succeed." << endl;
// 加载函数
PyObject* pv = PyObject_GetAttrString(pModule, "test_add");
PyErr_Print();
if (!pv || !PyCallable_Check(pv)) // 验证是否加载成功
{
cout << "[ERROR] Can't find funftion (test_add)" << endl;
return 0;
}
cout << "[INFO] Get function (test_add) succeed!!!" << endl;
// 设置参数
PyObject* args = PyTuple_New(2); // 2个参数
PyObject* arg1 = PyInt_FromLong(4); // 参数一设为4
PyObject* arg2 = PyInt_FromLong(3); // 参数二设为3
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
// 调用函数
PyObject* pRet = PyObject_CallObject(pv, args);
// 获取参数
if (pRet) // 验证是否调用成功
{
long result = PyInt_AsLong(pRet);
cout << "result:" << result << endl;
}
Py_Finalize();
return 0;
}
python代码[ab.py]:
def test_add(a, b):
print a,b
print a+b
return a+b
参考文献:
c++调用python脚本
Linux下C++调用python,gcc和eclipse的编译方法
Embedding Python in Another Applicatio