日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

深入淺析 C++ 調(diào)用 Python 模塊

系統(tǒng) 1774 0

一般開發(fā)過游戲的都知道Lua和C++可以很好的結(jié)合在一起,取長(zhǎng)補(bǔ)短,把Lua腳本當(dāng)成類似動(dòng)態(tài)鏈接庫(kù)來使用,很好的利用了腳本開發(fā)的靈活性。而作為一門流行的通用型腳本語言Python,也是可以做到的。在一個(gè)C++應(yīng)用程序中,我們可以用一組插件來實(shí)現(xiàn)一些具有統(tǒng)一接口的功能,一般插件都是使用動(dòng)態(tài)鏈接庫(kù)實(shí)現(xiàn),如果插件的變化比較頻繁,我們可以使用Python來代替動(dòng)態(tài)鏈接庫(kù)形式的插件(堪稱文本形式的動(dòng)態(tài)鏈接庫(kù)),這樣可以方便地根據(jù)需求的變化改寫腳本代碼,而不是必須重新編譯鏈接二進(jìn)制的動(dòng)態(tài)鏈接庫(kù)。靈活性大大的提高了。

作為一種膠水語言,Python 能夠很容易地調(diào)用 C 、 C++ 等語言,也能夠通過其他語言調(diào)用 Python 的模塊。

Python 提供了 C++ 庫(kù),使得開發(fā)者能很方便地從 C++ 程序中調(diào)用 Python 模塊。

具體的文檔參考官方指南:

Embedding Python in Another Application

調(diào)用方法

1 鏈接到 Python 調(diào)用庫(kù)

Python 安裝目錄下已經(jīng)包含頭文件( include 目錄)和庫(kù)文件 ( Windows 下為 python27.lib)。

使用之前需要鏈接到此庫(kù)。

2 直接調(diào)用 Python 語句

            
              #include "python/Python.h"
int main()
{
Py_Initialize(); ## 初始化
PyRun_SimpleString("print 'hello'");
Py_Finalize(); ## 釋放資源
}

            
          

3 加載 Python 模塊并調(diào)用函數(shù)

~/test 目錄下含有 test.py :

            
              def test_add(a, b):
print 'add ', a, ' and ', b
return a+b
            
          

則可以通過以下代碼調(diào)用 test_add 函數(shù) :

            
              #include "python/Python.h"
#include 
              
                
using namespace std;
int main()
{
Py_Initialize(); // 初始化
// 將Python工作路徑切換到待調(diào)用模塊所在目錄,一定要保證路徑名的正確性
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;
// 加載函數(shù)
PyObject* pv = PyObject_GetAttrString(pModule, "test_add");
if (!pv || !PyCallable_Check(pv)) // 驗(yàn)證是否加載成功
{
cout << "[ERROR] Can't find funftion (test_add)" << endl;
return 0;
}
cout << "[INFO] Get function (test_add) succeed." << endl;
// 設(shè)置參數(shù)
PyObject* args = PyTuple_New(2); // 2個(gè)參數(shù)
PyObject* arg1 = PyInt_FromLong(4); // 參數(shù)一設(shè)為4
PyObject* arg2 = PyInt_FromLong(3); // 參數(shù)二設(shè)為3
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
// 調(diào)用函數(shù)
PyObject* pRet = PyObject_CallObject(pv, args);
// 獲取參數(shù)
if (pRet) // 驗(yàn)證是否調(diào)用成功
{
long result = PyInt_AsLong(pRet);
cout << "result:" << result;
}
Py_Finalize(); ## 釋放資源
return 0;
}

              
            
          

參數(shù)傳遞

1 C++ 向 Python 傳遞參數(shù)

Python 的參數(shù)實(shí)際上是元組,因此傳參實(shí)際上就是構(gòu)造一個(gè)合適的元組。

常用的有兩種方法:

使用 PyTuple_New 創(chuàng)建元組, PyTuple_SetItem 設(shè)置元組值

            
              PyObject* args = PyTuple_New(3);
PyObject* arg1 = Py_BuildValue("i", 100); // 整數(shù)參數(shù)
PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮點(diǎn)數(shù)參數(shù)
PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串參數(shù)
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
PyTuple_SetItem(args, 2, arg3);
            
          

直接使用Py_BuildValue構(gòu)造元組

            
              PyObject* args = Py_BuildValue("ifs", 100, 3.14, "hello");
PyObject* args = Py_BuildValue("()"); // 無參函數(shù)
            
          

i, s, f之類的格式字符串可以參考 格式字符串

2 轉(zhuǎn)換 Python 返回值

調(diào)用 Python 得到的都是PyObject對(duì)象,因此需要使用 Python 提供的庫(kù)里面的一些函數(shù)將返回值轉(zhuǎn)換為 C++ , 例如 PyInt_AsLong,PyFloat_AsDouble, PyString_AsString 等。

還可以使用 PyArg_ParseTuple 函數(shù)來將返回值作為元組解析。

PyArg_Parse 也是一個(gè)使用很方便的轉(zhuǎn)換函數(shù)。

PyArg_ParseTuple 和 PyArg_Parse 都使用 格式字符串

注意事項(xiàng)

需要將 Python 的工作目錄切換到模塊所在路徑 按照模塊名加載而不是文件名 模塊加載或者函數(shù)加載需要驗(yàn)證是否成功,否則可能會(huì)引起堆棧錯(cuò)誤導(dǎo)致程序崩潰 需要使用 Py_DECREF(PyObject*) 來解除對(duì)象的引用(以便Python垃圾回收)

以上所述是小編給大家介紹的C++ 調(diào)用 Python 模塊的相關(guān)知識(shí),希望對(duì)大家有所幫助!


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 江达县| 合作市| 微博| 澄迈县| 乌兰县| 南郑县| 类乌齐县| 镇江市| 洞口县| 阳谷县| 大邑县| 上林县| 亳州市| 板桥市| 峡江县| 宜川县| 鹿邑县| 永德县| 南平市| 中超| 华安县| 诏安县| 分宜县| 天柱县| 泸水县| 邯郸县| 汾西县| 黄骅市| 淮安市| 宁海县| 连云港市| 黄浦区| 中西区| 永平县| 光泽县| 琼中| 新乡县| 丰镇市| 开封县| 新营市| 涟水县|