轉載請注明來源:https://www.cnblogs.com/hookjc/
(1)初始化Python腳本運行環境
Py_Initialize();
(2) 腳本的編譯
bytecode = Py_CompileString(script.c_str() , "active" , Py_file_input)
python有多種embeded的形式,我最喜歡的是用Py_CompileString來編譯一個.py的腳本文件,這樣有下面幾個好處,引用方便,調試方便,靈活。
編譯好后會返回一個PyObject* 的bytecode對象
要注意的是.py腳本的格式很重要,一定記得換行用Unix方式的,否則是不會編譯通過的,我第一次時就找了很久才發現這個問題,還有一個要注意的問題是最好編一個調試版本的python的dll和庫,這樣便於發現問題。
(3)導入編譯好的腳本
module=PyImport_ExecCodeModule("active",bytecode),這個過程是構造庫的過程,運行完成之后就會把你要應用的Python庫裝入內存當中。
(4)從module中導出對象
dict = PyModule_GetDict( module )
導出對象表后你就可以按照你的需要使用你想用的python對象,這里常用的是類,方法,函數,我這里只用了最簡單全局函數,用fun = PyDict_GetItemString( dict , "active" );得到想要使用的函數對象。
(5)調用Python函數
還剩下一個問題了,如何給調用的Python函數傳遞參數
python函數的參數是一個Tuple類型的值,通俗的理解就是名字和對象的列表,這樣不管你傳遞多少參數,只要用一個Tuple類型就都解決了,代碼如下
args = PyTuple_New( argsnum );
if( !args )
{
PyErr_Print();
assert(false);
}
for( i = 0 ; i < argsnum ; i++ )
{
value = PyString_FromString( strings[i] );
PyTuple_SetItem( args , i , value );
}
用PyString_FromString等類型轉換函數就可以實現參數生成的過程了。
(6)調用函數,得到返回值
value = PyObject_CallObject( fun , args );
if(!value)
{
PyErr_Print();
assert(false);
}
value是PyObject用轉換函數就可以得到C++類型的返回值了,到這兒一個完整的調用過程就結束了
(7)其它
調用結束后釋放腳本運行環境Py_Finalize();
注意下面幾個問題,PyObject*都是有引用計數的,看文檔說明有些對象是要自己處理引用計數的用Py_DECREF來釋放對象,一般說如是類new操作的對象都要釋放對象,如果是通過query出來的對象一般不用釋放。
