您的位置:首页 > 编程语言 > C语言/C++

C++、Qt内嵌python

2017-09-25 08:09 489 查看

C++内嵌python

python重要的路径:

/usr/local/include/python3.6m
/usr/local/bin/python3-config
/usr/local/bin/python3.6
/usr/local/bin/python3
/usr/local/bin/python3.6-config
/usr/local/bin/python3.6m
/usr/local/bin/python3.6m-config
/usr/local/lib/python3.6
/usr/local/lib/python3.6/site-packages/numpy/lib/tests/data/python3.npy
/usr/local/lib/pkgconfig/python3.pc
/usr/local/share/man/man1/python3.1
/usr/local/share/man/man1/python3.6.1
/usr/share/vim/vim74/autoload/python3complete.vim
/usr/share/doc/python-setuptools-0.6.10/docs/python3.txt
/usr/share/doc/python-setuptools-0.6.10/docs/build/html/_sources/python3.txt


在文件
/usr/local/lib/pkgconfig/python-3.6.pc
中给出了引用头文件和连接库文件的信息:

# See: man pkg-config
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: Python
Description: Python library
Requires:
Version: 3.6
Libs.private: -lpthread -ldl  -lutil -lrt
Libs: -L${libdir} -lpython3.6m
Cflags: -I${includedir}/python3.6m


include路径包含了各种头文件:
/usr/local/include/python3.6m


库文件目录为:
/usr/local/lib
静态库文件是
libpython3.6m.a


C/C++中内嵌python的文章:http://python.usyiyi.cn/translate/python_352/c-api/intro.html#embedding-python

简单python引用

需要引用的py代码,pytest.py :

def show():
print("hello world!")


C++代码,test.cpp

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc,char **argv){
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/edemon/workspace/qt_cpp/untitled/tmp')");
// import py file.
PyObject* pModule = PyImport_ImportModule("pytest");
if(pModule == NULL){
cout<<"my test py file open failed.";
return -1;
}
// import function
PyObject* pyFun = PyObject_GetAttrString(pModule,"show");
if(pyFun == NULL){
cout<<"pyFun get failed.";
return -1;
}
// call function
PyObject_CallFunction(pyFun,NULL);
Py_Finalize();
return 0;
}


使用g++编译:
g++ test.cpp -I /usr/local/include/python3.6m -L/usr/local/lib -lpython3.6m -lrt -ldl -lutil -o test


C++内嵌导入其他模块的python

下面的程序是利用python安装的tushare模块请求顺丰控股的价位峰值数据

import tushare

def data_high():
print(tushare.get_hist_data(code='002352',start='2016-09-01',end='2016-09-20').high)
def data_low():
print(tushare.get_hist_data(code='002352',start='2016-09-01',end='2016-09-20').low)


在C++中引用相关的函数:

#include "Python.h"
#include <iostream>
using namespace std;

int main(int argc,char **argv){
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/edemon/workspace/qt_cpp/untitled/tmp/advanced')");
//PyRun_SimpleString("sys.path.append('/usr/local/lib/python3.6/site-packages/tushare')");

PyObject* pModule = PyImport_ImportModule("myData");
if(pModule == NULL){
cout<<"my test py file open failed.";
return -1;
}
PyObject* pDataHigh = PyObject_GetAttrString(pModule,"data_high");
if(pDataHigh == NULL){
cout<<"data_high get failed.";
return -1;
}
PyObject_CallFunction(pDataHigh,NULL);
Py_Finalize();
return 0;
}


运行:

$  g++ main.cpp -I /usr/local/include/python3.6m -L/usr/local/lib -lpython3.6m -lrt -ldl -lutil  -Xlinker -export-dynamic -o main
$ ./main
date
2016-09-20    45.52
2016-09-19    42.39
2016-09-14    40.80
2016-09-13    39.70
2016-09-12    39.87
2016-09-09    40.00
2016-09-08    38.99
2016-09-07    39.40
2016-09-06    39.12
2016-09-05    39.27
2016-09-02    40.49
2016-09-01    40.36
Name: high, dtype: float64


注意加上:
-Xlinker -export-dynamic
,动态链接库文件。

QT内嵌python

在工程文件pro中注意includepath和libs的设置:

# add extra info for qt
INCLUDEPATH += "/usr/local/include/python3.6m"
LIBS += "-L/usr/local/lib" -lpython3.6m -lrt -ldl -lutil -Xlinker -export-dynamic


和C++内嵌python的例子类似,这里将得到的峰值数据写入文件中。

data.py:

#! /usr/local/bin/python3
import os
import tushare

def data_high():
res = tushare.get_hist_data(code='002352',start='2016-09-01',end='2016-09-20').high
os.chdir("./")
res_file = open("result.txt","w")
print(res,file=res_file)
res_file.close()

def data_low():
return ts.get_hist_data(code='002352',start='2016-09-01',end='2016-09-20').low


main.cpp:

#include "Python.h"
#include <QApplication>
#include <QDebug>

int main(int argc,char **argv){
QApplication app(argc,argv);
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject* pModule = PyImport_ImportModule("data");
if(pModule == NULL){
qDebug()<<"data.py can't open failed.";
return -1;
}
PyObject* pDataHigh = PyObject_GetAttrString(pModule,"data_high");
if(pDataHigh == NULL){
qDebug()<<"data_high get failed.";
return -1;
}
PyObject_CallFunction(pDataHigh,NULL);
Py_Finalize();
return app.exec();
}


你可能在make的时候会遇到类似于这样的问题:

n file included from /usr/local/include/python3.6m/pytime.h:6:0,
from /usr/local/include/python3.6m/Python.h:65,
from main.cpp:2:
/usr/local/include/python3.6m/object.h:448:20: error: expected unqualified-id before ‘;’ token
PyType_Slot *slots;  /* terminated by slot==0. */
^


这是因为slots是qt的关键字,故在引用头文件的时候需先引用python,即
#include "Python.h"
不能在
#include <QApplication>
的后面。像这样:

#include <QApplication>
#include "Python.h"
#include <QDebug>


修改pro文件后,及时更新Makefile:
qmake -makefile
,然后再make即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: