深入淺析 C++ 呼叫 Python 模組

高洛峰
發布: 2017-02-20 10:37:13
原創
1248 人瀏覽過

Python 提供了 C++ 函式庫,讓開發者能很方便地從 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 呼叫庫

Pyt 它安裝目錄下已經包含頭庫文件(為python27.lib)。

使用之前需要連結到此庫。

2 直接呼叫Python 語句

<code class="language-cpp hljs ">#include "python/Python.h"
int main()
{
Py_Initialize(); ## 初始化
PyRun_SimpleString("print &#39;hello&#39;");
Py_Finalize(); ## 释放资源
}
</code>
登入後複製

3 載入Python 模組並呼叫函數

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

<code class="language-python hljs ">def test_add(a, b):
print &#39;add &#39;, a, &#39; and &#39;, b
return a+b</code>
登入後複製

參數傳遞

1 C++ 向Python 傳遞參數

Python 的參數參是元組,因此傳傳參數實際上是建構一個合適的元組實際上。

常用的有兩種方法:

使用PyTuple_New 建立元組, PyTuple_SetItem 設定元組值

<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&#39;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>
登入後複製

的格式字串可以參考格式字串

2 轉換Python 回傳值

呼叫Python 得到的都是PyObject對象,因此需要使用Python 提供的函式庫裡面的一些函數將回傳值轉換為C++ , 例如PyInt_AsLong,PyFloat_AsDouble, PyString_AsString等。

也可以使用 PyArg_ParseTuple 函數來將回傳值作為元組解析。

PyArg_Parse 也是使用很方便的轉換函數。

PyArg_ParseTuple 和PyArg_Parse 都使用格式字串

PyArg_ParseTuple 和PyArg_Parse 都使用格式字串

注意事項

需要將Python 的工作目錄切換到模組名稱以載入模組名稱而不是載入文件名稱可能會造成堆疊錯誤導致程式崩潰需要使用Py_DECREF(PyObject*) 來解除物件的參考(以便Python垃圾回收)

以上所述是小編給大家介紹的C++ 呼叫Python 模組的相關知識,希望對大家有所幫助!

更多深入淺析 C++ 呼叫 Python 模組相關文章請關注PHP中文網!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板