程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 深刻淺析 C++ 挪用 Python 模塊

深刻淺析 C++ 挪用 Python 模塊

編輯:關於C++

深刻淺析 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 模塊的相干常識,願望對年夜家有所贊助!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved