大家好,我又回來了!
貌似和python結下了不解之緣,最近主要在做python的擴展和嵌入。
在正式寫代碼之前,先嘮叨幾句環境的搭建。當時搭建環境的時候也是費了一番辛苦。【嘆氣】
在嵌入和擴展Python時,需要調用python的c api,則需要包含Python.h,若想成功的將其包含,需要安裝python dev。Ok,終於成功包含了Python.h,然後你歡天喜地的去運行程序了,發現編譯不過去。親,不要沮喪,離成功只差一步了,你只再需要編譯和鏈接一下。當時我自己也是在茫茫互聯網上搜索的啊~這部分主要看Python的官方文檔。
OK,接下來說下我的運行環境:ubuntu 14.04(32位),Qt Creator, Python3.5。
一、環境搭建
1. 安裝python dev,這部分不做詳細介紹。
2. 爲嵌入python解釋器,編譯和鏈接python的c動態庫。
①編譯時
python3.5-config --cflags
②鏈接時
python3.5-config --ldlags
Qt .pro裏面的配置如圖,需將終端顯示的都複製下來。
二、測試程序編寫
想在python裏面調用自己命名並且自己編寫的函數麼?那接下來就得看看了~
老規矩,先上程序:
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <python3.5/Python.h>
double add(double x, double y)
{
double sum = 0.0;
sum = x + y;
return sum;
}
static PyObject*
add(PyObject *self, PyObject *args)
{
(void)self;
PyObject *pArgs = NULL;
double x = 0.0, y = 0.0;
double result = 0.0;
if (!PyArg_ParseTuple(args,"dd",&x,&y))
{
Py_INCREF(Py_None);
pArgs = Py_None;
}
else
{
result = add(x,y);
pArgs = Py_BuildValue("d", result);
}
return pArgs;
}
static PyMethodDef MathMethods[] = {
{"add", add, METH_VARARGS,"add."},
{NULL, NULL, 0, NULL}
};
static PyModuleDef MathModule = {
PyModuleDef_HEAD_INIT, "dahe", NULL, -1, MathMethods,
NULL, NULL, NULL, NULL
};
static PyObject*
PyInit_math(void)
{
return PyModule_Create(&MathModule);
}
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pbn_runPython_clicked()
{
qDebug() << "enter python !";
PyImport_AppendInittab("dahe", &PyInit_math);
Py_Initialize();
if (!Py_IsInitialized())
{
qDebug() << "inital faild!";
}
PyRun_SimpleString("import os");
PyRun_SimpleString("print (os.getcwd())");
PyRun_SimpleString("import dahe");
PyRun_SimpleString("exec(open('dhTest.py', encoding = 'utf-8').read())");
Py_Finalize();
}
1. 程序說明
點擊按鈕,觸發槽函數執行,運行python c api。從腳本文件中傳入參數、計算、打印結果。
①要調用python的C api,需要包含Python.h
②double add(double x, double y)這個函數是python要調用的函數,我們編寫的很多程序是爲了傳遞參數和進行錯誤處理。結合上之前用Qt創建共享庫,這裏也可以調用共享庫的函數。
③在調用c api前,需要先初始化python解釋器,使用完成後要釋放解釋器。說明一點,python3中在初始化解釋器前,要將自己編寫的模塊進行註冊。
④PyRun_SimpleString()函數可直接運行python的語句,簡單使用時,常用的api不是特別多。
⑤python api中我獲得了python當前的執行路徑,運行了一個dhTest.py的python文件。
⑥更多信息需要參考python官網
2. 程序運行結果
大家如果覺得還闊以,請關注下方公衆號~