国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

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

2020-05-23 14:06:45
字體:
供稿:網(wǎng)友
Python 提供了 C++ 庫,使得開發(fā)者能很方便地從 C++ 程序中調(diào)用 Python 模塊。接下來通過本文給大家介紹 C++ 調(diào)用 Python 模塊的相關(guān)知識,需要的朋友參考下吧
 

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

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

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

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

Embedding Python in Another Application

調(diào)用方法

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

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

使用之前需要鏈接到此庫。

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

<code class="language-cpp hljs ">#include "python/Python.h"int main(){Py_Initialize(); ## 初始化PyRun_SimpleString("print 'hello'");Py_Finalize(); ## 釋放資源}</code>

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

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

<code class="language-python hljs ">def test_add(a, b):print 'add ', a, ' and ', breturn a+b</code>

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

<code class="language-cpp hljs ">#include "python/Python.h"#include <iostream>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)) // 驗證是否加載成功{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個參數(shù)PyObject* arg1 = PyInt_FromLong(4); // 參數(shù)一設(shè)為4PyObject* arg2 = PyInt_FromLong(3); // 參數(shù)二設(shè)為3PyTuple_SetItem(args, 0, arg1);PyTuple_SetItem(args, 1, arg2);// 調(diào)用函數(shù)PyObject* pRet = PyObject_CallObject(pv, args);// 獲取參數(shù)if (pRet) // 驗證是否調(diào)用成功{long result = PyInt_AsLong(pRet);cout << "result:" << result;}Py_Finalize(); ## 釋放資源return 0;}</iostream></code>

參數(shù)傳遞

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

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

常用的有兩種方法:

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

<code class="language-cpp hljs ">PyObject* args = PyTuple_New(3);PyObject* arg1 = Py_BuildValue("i", 100); // 整數(shù)參數(shù)PyObject* arg2 = Py_BuildValue("f", 3.14); // 浮點數(shù)參數(shù)PyObject* arg3 = Py_BuildValue("s", "hello"); // 字符串參數(shù)PyTuple_SetItem(args, 0, arg1);PyTuple_SetItem(args, 1, arg2);PyTuple_SetItem(args, 2, arg3);</code>

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

<code class="language-cpp hljs ">PyObject* args = Py_BuildValue("ifs", 100, 3.14, "hello");PyObject* args = Py_BuildValue("()"); // 無參函數(shù)</code>

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

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

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

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

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

PyArg_ParseTuple 和 PyArg_Parse 都使用 格式字符串

注意事項

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

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



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 安福县| 博客| 广安市| 琼结县| 镇巴县| 武功县| 咸丰县| 益阳市| 夹江县| 普陀区| 庆城县| 五家渠市| 武平县| 辽阳市| 乐陵市| 弋阳县| 永新县| 化隆| 会泽县| 贵港市| 九台市| 泰来县| 光山县| 固原市| 柳林县| 彭泽县| 双桥区| 阿拉尔市| 大余县| 北宁市| 宿州市| 东阿县| 安图县| 巴彦县| 革吉县| 休宁县| 盐池县| 华坪县| 剑河县| 庄浪县| 邯郸县|