深刻淺析 C++ 挪用 Python 模塊。本站提示廣大學習愛好者:(深刻淺析 C++ 挪用 Python 模塊)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻淺析 C++ 挪用 Python 模塊正文
普通開辟過游戲的都曉得Lua和C++可以很好的聯合在一路,揚長避短,把Lua劇本當做相似靜態鏈接庫來應用,很好的應用了劇本開辟的靈巧性。而作為一門風行的通用型劇本說話Python,也是可以做到的。在一個C++運用法式中,我們可以用一組插件來完成一些具有同一接口的功效,普通插件都是應用靜態鏈接庫完成,假如插件的變更比擬頻仍,我們可使用Python來取代靜態鏈接庫情勢的插件(可謂文本情勢的靜態鏈接庫),如許可以便利地依據需求的變更改寫劇本代碼,而不是必需從新編譯鏈接二進制的靜態鏈接庫。靈巧性年夜年夜的進步了。
作為一種膠水說話,Python 可以或許很輕易地挪用 C 、 C++ 等說話,也可以或許經由過程其他說話挪用 Python 的模塊。
Python 供給了 C++ 庫,使得開辟者能很便利地從 C++ 法式中挪用 Python 模塊。
詳細的文檔參考官方指南:
Embedding Python in Another Application
挪用辦法
1 鏈接到 Python 挪用庫
Python 裝置目次下曾經包括頭文件( include 目次)和庫文件 ( Windows 下為 python27.lib)。
應用之前須要鏈接到此庫。
2 直接挪用 Python 語句
<code class="language-cpp hljs ">#include "python/Python.h" int main() { Py_Initialize(); ## 初始化 PyRun_SimpleString("print 'hello'"); Py_Finalize(); ## 釋放資本 } </code>
3 加載 Python 模塊並挪用函數
~/test 目次下含有 test.py :
<code class="language-python hljs ">def test_add(a, b): print 'add ', a, ' and ', b return a+b</code>
則可以經由過程以下代碼挪用 test_add 函數 :
<code class="language-cpp hljs ">#include "python/Python.h" #include <iostream> using namespace std; int main() { Py_Initialize(); // 初始化 // 將Python任務途徑切換到待挪用模塊地點目次,必定要包管途徑名的准確性 string path = "~/test"; string chdir_cmd = string("sys.path.append(\"") + path + "\")"; const char* cstr_cmd = chdir_cmd.c_str(); PyRun_SimpleString("import sys"); PyRun_SimpleString(cstr_cmd); // 加載模塊 PyObject* moduleName = PyString_FromString("test"); //模塊名,不是文件名 PyObject* pModule = PyImport_Import(moduleName); if (!pModule) // 加載模塊掉敗 { cout << "[ERROR] Python get module failed." << endl; return 0; } cout << "[INFO] Python get module succeed." << endl; // 加載函數 PyObject* pv = PyObject_GetAttrString(pModule, "test_add"); if (!pv || !PyCallable_Check(pv)) // 驗證能否加載勝利 { cout << "[ERROR] Can't find funftion (test_add)" << endl; return 0; } cout << "[INFO] Get function (test_add) succeed." << endl; // 設置參數 PyObject* args = PyTuple_New(2); // 2個參數 PyObject* arg1 = PyInt_FromLong(4); // 參數一設為4 PyObject* arg2 = PyInt_FromLong(3); // 參數二設為3 PyTuple_SetItem(args, 0, arg1); PyTuple_SetItem(args, 1, arg2); // 挪用函數 PyObject* pRet = PyObject_CallObject(pv, args); // 獲得參數 if (pRet) // 驗證能否挪用勝利 { long result = PyInt_AsLong(pRet); cout << "result:" << result; } Py_Finalize(); ## 釋放資本 return 0; } </iostream></code>
參數傳遞
1 C++ 向 Python 傳遞參數
Python 的參數現實上是元組,是以傳參現實上就是結構一個適合的元組。
經常使用的有兩種辦法:
應用 PyTuple_New 創立元組, PyTuple_SetItem 設置元組值
<code class="language-cpp hljs ">PyObject* args = PyTuple_New(3); PyObject* arg1 = Py_BuildValue("i", 100); // 整數參數 PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮點數參數 PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串參數 PyTuple_SetItem(args, 0, arg1); PyTuple_SetItem(args, 1, arg2); PyTuple_SetItem(args, 2, arg3);</code>
直接應用Py_BuildValue結構元組
<code class="language-cpp hljs ">PyObject* args = Py_BuildValue("ifs", 100, 3.14, "hello"); PyObject* args = Py_BuildValue("()"); // 無參函數</code>
i, s, f之類的格局字符串可以參考 格局字符串
2 轉換 Python 前往值
挪用 Python 獲得的都是PyObject對象,是以須要應用 Python 供給的庫外面的一些函數將前往值轉換為 C++ , 例如 PyInt_AsLong,PyFloat_AsDouble, PyString_AsString 等。
還可使用 PyArg_ParseTuple 函數來將前往值作為元組解析。
PyArg_Parse 也是一個應用很便利的轉換函數。
PyArg_ParseTuple 和 PyArg_Parse 都應用 格局字符串
留意事項
須要將 Python 的任務目次切換到模塊地點途徑 依照模塊名加載而不是文件名 模塊加載或許函數加載須要驗證能否勝利,不然能夠會惹起客棧毛病招致法式瓦解 須要應用 Py_DECREF(PyObject*) 來消除對象的援用(以便Python渣滓收受接管)
以上所述是小編給年夜家引見的C++ 挪用 Python 模塊的相干常識,願望對年夜家有所贊助!