Heim  >  Artikel  >  Backend-Entwicklung  >  Eine ausführliche Analyse des C++-Aufrufs von Python-Modulen

Eine ausführliche Analyse des C++-Aufrufs von Python-Modulen

高洛峰
高洛峰Original
2017-02-20 10:37:131243Durchsuche

Python bietet eine C++-Bibliothek, die es Entwicklern ermöglicht, Python-Module einfach aus C++-Programmen aufzurufen. Als Nächstes stellt Ihnen dieser Artikel das relevante Wissen zum Aufrufen von Python-Modulen in C++ vor. Freunde, die es benötigen, können darauf zurückgreifen.

Im Allgemeinen wissen diejenigen, die Spiele entwickelt haben, dass Lua und C++ gut kombiniert werden können Die Stärken des anderen nutzen und Lua-Skripte verwenden. Es wird wie eine dynamische Linkbibliothek verwendet und nutzt die Flexibilität der Skriptentwicklung gut aus. Als beliebte Allzweck-Skriptsprache kann Python dies ebenfalls. In einer C++-Anwendung können wir eine Reihe von Plug-Ins verwenden, um einige Funktionen mit einer einheitlichen Schnittstelle zu implementieren. Im Allgemeinen werden Plug-Ins mithilfe dynamischer Linkbibliotheken implementiert. Wenn sich die Plug-Ins häufig ändern, können wir stattdessen Python verwenden Plug-Ins (die in Textform als dynamische Linkbibliotheken bezeichnet werden können) erleichtern das Umschreiben von Skriptcode entsprechend sich ändernden Anforderungen, anstatt binäre dynamische Linkbibliotheken neu kompilieren und verknüpfen zu müssen. Die Flexibilität wird erheblich verbessert.

Als Leimsprache kann Python problemlos C, C++ und andere Sprachen aufrufen und auch Python-Module über andere Sprachen aufrufen.

Python bietet eine C++-Bibliothek, die es Entwicklern ermöglicht, Python-Module einfach aus C++-Programmen aufzurufen.

Eine spezifische Dokumentation finden Sie im offiziellen Leitfaden:

Python in eine andere Anwendung einbetten

Aufrufmethode

1 Link zur Python-Aufrufbibliothek

Das Python-Installationsverzeichnis enthält bereits Header-Dateien (einschließlich Verzeichnis) und Bibliotheksdateien (python27.lib unter Windows).

Sie müssen eine Verknüpfung zu dieser Bibliothek herstellen, bevor Sie sie verwenden können.

2 Rufen Sie direkt die Python-Anweisung auf

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

3 Laden Sie das Python-Modul und rufen Sie die Funktion auf

~/ Das Testverzeichnis enthält test.py:

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

. Sie können die Funktion test_add über den folgenden Code aufrufen:

<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>

Parameterübergabe

1 C++ übergibt Parameter an Python

Python-Parameter sind eigentlich Tupel, daher ist die Übergabe von Parametern tatsächlich die Konstruktion eines geeigneten Tupels.

Es gibt zwei häufig verwendete Methoden:

Verwenden Sie PyTuple_New, um ein Tupel zu erstellen, und PyTuple_SetItem, um den Tupelwert festzulegen

<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>

Verwenden Sie Py_BuildValue direkt, um Tupel zu erstellen

<code class="language-cpp hljs ">PyObject* args = Py_BuildValue("ifs", 100, 3.14, "hello");
PyObject* args = Py_BuildValue("()"); // 无参函数</code>

Formatzeichenfolgen wie i, s, f finden Sie in der Formatzeichenfolge

2 Python-Rückgabewert konvertieren

Was Sie beim Aufruf von Python erhalten, sind PyObject-Objekte. Sie müssen daher einige Funktionen in der von Python bereitgestellten Bibliothek verwenden, um den Rückgabewert in C++ zu konvertieren, z. B. PyInt_AsLong, PyFloat_AsDouble , PyString_AsString usw.

Sie können auch die Funktion PyArg_ParseTuple verwenden, um den Rückgabewert als Tupel zu analysieren.

PyArg_Parse ist auch eine Konvertierungsfunktion, die sehr praktisch ist.

Sowohl PyArg_ParseTuple als auch PyArg_Parse verwenden Formatzeichenfolgen

Hinweise

Sie müssen das Python-Arbeitsverzeichnis dorthin wechseln, wo sich das Modul befindet Es muss überprüft werden, ob das Laden des Moduls oder das Laden der Funktion erfolgreich ist. Andernfalls kann es zu einem Stapelfehler und zum Absturz des Programms kommen. Sie müssen Py_DECREF verwenden (PyObject*) zum Dereferenzieren des Objekts (für die Python-Garbage-Collection)

Das Obige ist das vom Herausgeber eingeführte relevante Wissen über C++-Aufrufe von Python-Modulen. Ich hoffe, es wird für alle hilfreich sein!

Für eine ausführlichere Analyse von C++-aufrufenden Python-Modulen beachten Sie bitte die chinesische PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn