C++調用Python(3)

來源:互聯網
上載者:User

    前兩篇都是介紹Python調用C++的,換句話說,就是需要把C++封裝成Python可以“理解”的類型。這篇,我打算說一下,C++怎麼去調用Python指令碼。其實這兩者之間是相通的,就是需要可以互操作。按照慣例,先貼代碼。
test.cpp

/*<br /> * test.cpp<br /> * Created on: 2010-8-12<br /> * Author: lihaibo<br /> */<br />#include <python2.6/Python.h><br />#include <iostream><br />#include <string><br />void printDict(PyObject* obj) {<br />if (!PyDict_Check(obj))<br />return;<br />PyObject *k, *keys;<br />keys = PyDict_Keys(obj);<br />for (int i = 0; i < PyList_GET_SIZE(keys); i++) {<br />k = PyList_GET_ITEM(keys, i);<br />char* c_name = PyString_AsString(k);<br />printf("%s/n", c_name);<br />}<br />}<br />int main() {<br />Py_Initialize();<br />if (!Py_IsInitialized())<br />return -1;<br />PyRun_SimpleString("import sys");<br />PyRun_SimpleString("sys.path.append('./')");<br />//匯入模組<br />PyObject* pModule = PyImport_ImportModule("testpy");<br />if (!pModule) {<br />printf("Cant open python file!/n");<br />return -1;<br />}<br />//模組的字典列表<br />PyObject* pDict = PyModule_GetDict(pModule);<br />if (!pDict) {<br />printf("Cant find dictionary./n");<br />return -1;<br />}<br />//列印出來看一下<br />printDict(pDict);<br />//示範函數調用<br />PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");<br />PyObject_CallFunction(pFunHi, "s", "lhb");<br />Py_DECREF(pFunHi);<br />//示範構造一個Python對象,並調用Class的方法<br />//擷取Second類<br />PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");<br />if (!pClassSecond) {<br />printf("Cant find second class./n");<br />return -1;<br />}<br />//擷取Person類<br />PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person");<br />if (!pClassPerson) {<br />printf("Cant find person class./n");<br />return -1;<br />}<br />//構造Second的執行個體<br />PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);<br />if (!pInstanceSecond) {<br />printf("Cant create second instance./n");<br />return -1;<br />}<br />//構造Person的執行個體<br />PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);<br />if (!pInstancePerson) {<br />printf("Cant find person instance./n");<br />return -1;<br />}<br />//把person執行個體傳入second的invoke方法<br />PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson);<br />//釋放<br />Py_DECREF(pInstanceSecond);<br />Py_DECREF(pInstancePerson);<br />Py_DECREF(pClassSecond);<br />Py_DECREF(pClassPerson);<br />Py_DECREF(pModule);<br />Py_Finalize();<br />return 0;<br />}<br />

編譯

g++ test.cpp -o test -lpython2.6

 

testpy.py

#!/usr/bin/python<br /># Filename: test.py<br />class Person:<br />def sayHi(self):<br />print 'hi'<br />class Second:<br />def invoke(self,obj):<br /> obj.sayHi()<br />def sayhi(name):<br />print 'hi',name;<br />

執行

lhb@localhost:~/maplib/clib/pyc/invokepy$ ./test
sayhi
__builtins__
__file__
__package__
Person
Second
__name__
__doc__
hi lhb
hi

我簡單解釋一下

  • 這個例子示範了,建立python中Person類的執行個體,並作為參數調用Second的方法。
  • Py_Initialize()和
    Py_Finalize()是初始和銷毀Python解譯器
  • PyRun_SimpleString(
    "import sys"
    )匯入sys,接著設定py檔案的路徑PyRun_SimpleString(
    "sys.path.append('./')"
    )
  • 匯入模組PyImport_ImportModule(
    "testpy"
    ),就是testpy.py模組。
  • 擷取模組字典列表,PyModule_GetDict(pModule),可以列印出來看一下如
    void
     printDict(PyObject* obj)函數
  • 從字典中擷取類的類型
    PyDict_GetItemString(pDict,
    "Second"
    ),如函數也是這樣擷取的
  • 創造類的執行個體
    PyInstance_New(pClassSecond,NULL,NULL)
  • 調用執行個體的方法PyObject_CallMethod(pInstanceSecond,
    "invoke"
    ,
    "O"
    ,pInstancePerson)

整個流程就是這樣的,並不複雜,如果要進一步研究可以參考:http://www.python.org/doc/

  • Extending and Embedding
  • Python/C API

比較特殊的是調用Python函數時,參數的傳遞,就是c++的類型,怎麼轉換成Python的類型;另外一個問題是,Python函數的傳回值,怎麼轉換成C++中的類型。
C++轉換成Python類型,Py_BuildValue()
http://www.python.org/doc/1.5.2p2/ext/buildValue.html

  1. PyObject* pArgs=PyTuple_New(
    1
    ); //有幾個參數,就是幾
  2. PyTuple_SetItem(pArgs,
    0
    ,Py_BuildValue(
    "i"
    ,
    3
    ));  //初始第一個參數,資料類型是i,就是int,值是
    3

傳回值轉換如,PyArg_ParseTuple,請參考
http://www.python.org/doc/1.5.2p2/ext/parseTuple.html

系列文章:
Python調用C/C++函數(1)
Python調用採用Boost Python封裝的c++(2)
C++調用Python(3)
C++調用Python(4)
c++和Python互操作進階應用程式(5)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.