Python嵌入C++詳解(1)--HelloWorld
來CSDN的時候,剛剛接觸Python,那時候對Python的嵌入部分高度興趣,只是一直沒有時間來弄清其面紗,因此也一直沒有使用嵌入的功能,另一個原因是我還沒有真正用Python寫過一個正式的有用點的東西,不過,現在回過頭來繼續看這一部分,發現還是挺簡單的。以前想把這部分翻譯出來,可是由於時間原因,也沒有那精力,所以這裡我會將我所探究的每個Python/C嵌入部分函數都用執行個體來說明,我想看代碼比我解釋要通俗易懂。
再說helloworld之前,先不得不提下嵌入的配置問題。
步驟:
1:請到官網下載python的安裝程式,安裝python(我想這步有點多餘,不過還是寫上吧)
2:接著你可能還需要下載python(與安裝版本相同)原始碼,因為我們需要在debug下編譯連結產生對應的debug庫,若你能在網上找到別人已經編譯好的庫,你也可以直接用別人的。這樣得到2個debug版本的.lib和.dll
3:將python目錄下的include檔案夾下的檔案移到編譯系統的include中,然後將release和debug版本的.lib和.dll放到指定的檔案夾中(lib放到編譯系統lib,dll放到windows/system32/)
4:好了,配置就此完成了。
來看代碼:
#include "python/python.h" //我是將python那些標頭檔放在我自己建的名為python的檔案夾中
int main(int argc,char** argv)
{
Py_Initialize();//該函數啟動python解譯器,算是初始化
////////////////////////
//載入檔案的方式運行指令,FILE是C標準庫stdio.h檔案中的一個結構,習慣C語言的應該很熟悉(不過我還是第一次使用,汗...)
FILE * fr;
fopen_s(&fr,"test.txt","r");
PyRun_SimpleFile(fr,"test.txt");
fclose(fr);
//直接運行指令,指令都是字串,注意3.1.1版的python必須加上小括弧
PyRun_SimpleString("print('Hello world,I am python!')");
///////////////////////
Py_Finalize(); //該函數關閉python解譯器,算是掃尾
return 0;
}
//附帶test.txt
/*
from time import time,ctime
print('Today is', ctime(time()))
*/
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/xiadasong007/archive/2009/09/02/4511841.aspx
Python嵌入C++詳解(2)--Import Module
首先,我不得不提到一個非常好的網站:http://www.codase.com/index.html
這是我在尋找嵌入函數時發現的,裡面有非常多的執行個體小代碼,實在是相見恨晚啊(呵呵)
前面說明了嵌入需要的配置(見http://blog.csdn.net/xiadasong007/archive/2009/09/02/4511841.aspx),這次主要是為了說明如何在C/C++中調用Python模組中的函數的基本方法。
前置說明:
1:PyObject * obj這個東西有點像SDK中控制代碼的感覺。
2:調用Python模組流程:首先要載入模組,載入完後就可以直接存取了(⊙o⊙)哦~!很簡單的~
好,來看代碼:
#include "python/python.h"
#include <iostream>
using namespace std;
int main(int argc,char** argv)
{
PyObject *pModule, *pFunc, *pValue;
Py_Initialize();
////////////////
pModule=PyImport_ImportModule("mat"); //mat是我自己用python寫的一個小模組(mat.py),裡面內容見後面附錄
pValue=PyObject_CallMethod(pModule,"add","ii",10,20); //通過上面得到的模組直接存取模組裡面的函數add(a,b)
//注意這裡的"ii"事實上相當於C中的"%d%d"的功能,請參考文檔
cout<<PyLong_AsLong(pValue)<<endl; //將得到的pValue值轉換為C中的long型
pFunc=PyObject_GetAttrString(pModule, "add"); //也可以使用該函數得到函數對象
pValue=PyObject_CallFunction(pFunc,"ii",1,2); //通過函數對象執行函數
cout<<PyLong_AsLong(pValue)<<endl;
////////////////
Py_Finalize();
return 0;
}
//附錄:mat.py
/*
def add(a,b):
return a+b
*/
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/xiadasong007/archive/2009/09/02/4512797.aspx
Python嵌入C++詳解(3)--Import Class
繼前篇《Import Module》(http://blog.csdn.net/xiadasong007/archive/2009/09/02/4512797.aspx),繼續分析嵌入部分基礎知識。這次不多說,有什麼問題記得多查英文資料,國內的這方面知識少
還是來看代碼,寫完我就睡覺了~
#include "python/python.h"
#include <iostream>
using namespace std;
int main(int argc,char** argv)
{
PyObject *pModule, *pClass,*pStuObj,*pFunc;
Py_Initialize();
////////////////
//載入模組stu.py
pModule = PyImport_ImportModule ("stu");
//從模組中得到類Student
pClass = PyObject_GetAttrString (pModule, "Student");
//產生一個學生對象jack,注意3.1版本必須加上小括弧:(s),否則會出錯
//PyObject_CallObject和另外一個常用的PyEval_CallObject用法極為相近,請看附錄部分詳解
PyObject * temp=Py_BuildValue("(s)","jack");
pStuObj = PyObject_CallObject(pClass, temp);
//獲得函數對象jack中的成員函數printName,
//這個getattr的意思就是得到當前對象的屬性(不要局限於C++中的屬性哦)
pFunc= PyObject_GetAttrString (pStuObj, "printName");
//調用函數printName
PyEval_CallObject (pFunc, NULL);
////////////////
Py_Finalize();
return 0;
}
/*
附錄:
1:Student類,我發現print後面現在必須加上小括弧了,否則會有問題
class Student:
name=""
def __init__(self,name):
self.name=name
def printName(self):
print (self.name)
2:PyObject_CallObject和 PyEval_CallObject不同之處:
可以看出,後者較為直接,而且接受NULL,and does explicit type checks
for args and kwds.
PyObject_CallObject(PyObject *o, PyObject *a)
{
! PyObject *r;
! PyObject *args = a;
!
! if (args == NULL) {
! args = PyTuple_New(0);
! if (args == NULL)
! return NULL;
! }
!
! r = PyEval_CallObject(o, args);
!
! if (args != a) {
! Py_DECREF(args);
! }
!
! return r;
}
PyObject_CallObject(PyObject *o, PyObject *a)
{
! return PyEval_CallObjectWithKeywords(o, a, NULL);
}
*/
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/xiadasong007/archive/2009/09/03/4513615.aspx