C++調用 Python

fmms 12年前發布 | 45K 次閱讀 Python C/C++開發

采用Python腳本解釋器進行腳本編譯及腳本解釋執行,而MT中主要采用C++編寫,C++需要import py_compile模塊進行腳本編譯。

C++調用Python的實例如下:

/* 

 * test.cpp 

 *  Created on: 2010-12-12 

 *      Author: Handy_Zhou 

 */  

#include <python2.6/Python.h>  


#include <iostream>  

#include <string>  

void printDict(PyObject* obj) {  

    if (!PyDict_Check(obj))  

        return;  

    PyObject *k, *keys;  

    keys = PyDict_Keys(obj);  

    for (int i = 0; i < PyList_GET_SIZE(keys); i++) {  

        k = PyList_GET_ITEM(keys, i);  

        char* c_name = PyString_AsString(k);  

        printf("%s\n", c_name);  

    }  

}  

int main() {  

    Py_Initialize();  

    if (!Py_IsInitialized())  

        return -1;  

    PyRun_SimpleString("import sys");  

    PyRun_SimpleString("sys.path.append('./')");  

    //導入模塊  

    PyObject* pModule = PyImport_ImportModule("testpy");  

    if (!pModule) {  

        printf("Cant open python file!\n");  

        return -1;  

    }  

    //模塊的字典列表  

    PyObject* pDict = PyModule_GetDict(pModule);  

    if (!pDict) {  

        printf("Cant find dictionary.\n");  

        return -1;  

    }  

    //打印出來看一下  

    printDict(pDict);  

    //演示函數調用  

    PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");  

    PyObject_CallFunction(pFunHi, "s", "lhb");  

    Py_DECREF(pFunHi);  

    //演示構造一個Python對象,并調用Class的方法  

    //獲取Second類  

    PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");  

    if (!pClassSecond) {  

        printf("Cant find second class.\n");  

        return -1;  

    }  

    //獲取Person類  

    PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person");  

    if (!pClassPerson) {  

        printf("Cant find person class.\n");  

        return -1;  

    }  

    //構造Second的實例  

    PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);  

    if (!pInstanceSecond) {  

        printf("Cant create second instance.\n");  

        return -1;  

    }  

    //構造Person的實例  

    PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);  

    if (!pInstancePerson) {  

        printf("Cant find person instance.\n");  

        return -1;  

    }  

    //把person實例傳入second的invoke方法  

    PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson);  

    //釋放  
     Py_DECREF(pInstanceSecond);  
    Py_DECREF(pInstancePerson);  
    Py_DECREF(pClassSecond);  
    Py_DECREF(pClassPerson);  
    Py_DECREF(pModule);  
    Py_Finalize();  

    return 0;  

} 

Python 源碼

#!/usr/bin/python  
# Filename: test.py  

class Person:  
    def sayHi(self):  
        print 'hi'  

class Second:  
    def invoke(self,obj):  
        obj.sayHi()  

def sayhi(name):  
    print 'hi',name;  

執行

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


PyObject* pArgs=PyTuple_New( 1 ); //有幾個參數,就是幾

PyTuple_SetItem(pArgs, 0 ,Py_BuildValue( "i" , 3 ));  //初始第一個參數,數據類型是i,就是int,值是 3

返回值轉換如,PyArg_ParseTuple,請參考

http://www.python.org/doc/1.5.2p2/ext/parseTuple.html

出處:
http://hi.baidu.com/zhouhanqing/blog/item/75b6134f2bddd91cb2de051a.html

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!