午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

C++調(diào)用Python(3)

 MikeDoc 2011-11-22
前兩篇都是介紹Python調(diào)用C++的,換句話說,就是需要把C++封裝成Python可以“理解”的類型。這篇,我打算說一下,C++怎么去調(diào)用Python腳本。其實(shí)這兩者之間是相通的,就是需要可以互操作。按照慣例,先貼代碼。
test.cpp

view plain
/*
* test.cpp
* Created on: 2010-8-12
* Author: lihaibo
*/
#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('./')");
//導(dǎo)入模塊
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);
//演示函數(shù)調(diào)用
PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");
PyObject_CallFunction(pFunHi, "s", "lhb");
Py_DECREF(pFunHi);
//演示構(gòu)造一個Python對象,并調(diào)用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;
}
//構(gòu)造Second的實(shí)例
PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL);
if (!pInstanceSecond) {
printf("Cant create second instance./n");
return -1;
}
//構(gòu)造Person的實(shí)例
PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL);
if (!pInstancePerson) {
printf("Cant find person instance./n");
return -1;
}
//把person實(shí)例傳入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;
}

編譯

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



testpy.py

view plain
#!/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;

執(zhí)行

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

我簡單解釋一下
這個例子演示了,創(chuàng)建python中Person類的實(shí)例,并作為參數(shù)調(diào)用Second的方法。
Py_Initialize()和 Py_Finalize()是初始和銷毀Python解釋器
PyRun_SimpleString( "import sys" )導(dǎo)入sys,接著設(shè)置py文件的路徑PyRun_SimpleString( "sys.path.append('./')" )
導(dǎo)入模塊PyImport_ImportModule( "testpy" ),就是testpy.py模塊。
獲取模塊字典列表,PyModule_GetDict(pModule),可以打印出來看一下如 void printDict(PyObject* obj)函數(shù)
從字典中獲取類的類型 PyDict_GetItemString(pDict, "Second" ),如函數(shù)也是這樣獲取的
創(chuàng)造類的實(shí)例 PyInstance_New(pClassSecond,NULL,NULL)
調(diào)用實(shí)例的方法PyObject_CallMethod(pInstanceSecond, "invoke" , "O" ,pInstancePerson)

整個流程就是這樣的,并不復(fù)雜,如果要進(jìn)一步研究可以參考:http://www./doc/
Extending and Embedding
Python/C API

比較特殊的是調(diào)用Python函數(shù)時,參數(shù)的傳遞,就是c++的類型,怎么轉(zhuǎn)換成Python的類型;另外一個問題是,Python函數(shù)的返回值,怎么轉(zhuǎn)換成C++中的類型。
C++轉(zhuǎn)換成Python類型,Py_BuildValue()
http://www./doc/1.5.2p2/ext/buildValue.html
PyObject* pArgs=PyTuple_New( 1 ); //有幾個參數(shù),就是幾
PyTuple_SetItem(pArgs, 0 ,Py_BuildValue( "i" , 3 )); //初始第一個參數(shù),數(shù)據(jù)類型是i,就是int,值是 3

返回值轉(zhuǎn)換如,PyArg_ParseTuple,請參考
http://www./doc/1.5.2p2/ext/parseTuple.html
系列文章:
Python調(diào)用C/C++函數(shù)(1)
Python調(diào)用采用Boost Python封裝的c++(2)
C++調(diào)用Python(3)
C++調(diào)用Python(4)

c++和Python互操作高級應(yīng)用(5)


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多