ホームページ >バックエンド開発 >Python チュートリアル >Python モジュールを呼び出す C++ の詳細な分析
Python は C++ ライブラリを提供しており、開発者は C++ プログラムから Python モジュールを簡単に呼び出すことができます。次に、この記事を通じて、Python モジュールを呼び出す C++ の関連知識を紹介します。必要な友人は参照してください
一般に、ゲームを開発したことがある人は、Lua と C++ をうまく組み合わせることができることを知っており、それぞれから学びます。 Lua スクリプトをダイナミック リンクと同様に扱うことで、スクリプト開発の柔軟性を最大限に活用できます。人気の汎用スクリプト言語である Python でもそれが可能です。 C++ アプリケーションでは、プラグインのセットを使用して、統一されたインターフェイスでいくつかの機能を実装できます。通常、プラグインはダイナミック リンク ライブラリを使用して実装されます。プラグインが頻繁に変更される場合は、ダイナミック リンクの代わりに Python を使用できます。プラグイン (テキスト形式ではダイナミック リンク ライブラリと呼ぶこともできます) を使用すると、バイナリ ダイナミック リンク ライブラリを再コンパイルしてリンクする必要がなく、要件の変更に応じてスクリプト コードを簡単に書き直すことができます。柔軟性が大幅に向上します。
Python はグルー言語として、C、C++、その他の言語を簡単に呼び出すことができ、また、他の言語を通じて Python モジュールを呼び出すこともできます。
Python は C++ ライブラリを提供しており、開発者は C++ プログラムから Python モジュールを簡単に呼び出すことができます。
特定のドキュメントについては、公式ガイドを参照してください:
別のアプリケーションへの Python の埋め込み
メソッドの呼び出し
1 Python 呼び出しライブラリへのリンク
Python インストール ディレクトリには、ヘッダー ファイル (インクルード ディレクトリ) とライブラリ ファイルが既に含まれています(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 パラメータは実際にはタプルなので、パラメータを渡すことは実際には適切なタプルを構築することになります。
一般的に使用されるメソッドは 2 つあります:
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 class フォーマット文字列については、フォーマット文字列を参照してください
2 Python の戻り値を変換する
Python を呼び出したときに取得するものは PyObject オブジェクトであるため、戻り値を C++ に変換するには、Python が提供するライブラリ内のいくつかの関数を使用する必要があります。 PyInt_AsLong、PyFloat_AsDouble、PyString_AsString などの待機。
PyArg_ParseTuple 関数を使用して、戻り値をタプルとして解析することもできます。
PyArg_Parse も非常に便利な変換関数です。
PyArg_ParseTuple と PyArg_Parse は両方ともフォーマット文字列を使用します
Notes
ファイル名ではなくモジュール名に従ってモジュールをロードする必要があります。読み込みまたは関数の読み込みが正常に検証される必要があります。そうでないと、スタック エラーが発生し、プログラムがクラッシュする可能性があります。オブジェクトを逆参照するには、Py_DECREF(PyObject*) を使用する必要があります (Python ガベージ コレクション用)。上記は関連するものです。エディターが紹介した C++ 呼び出し Python モジュールの知識が皆さんのお役に立てば幸いです。
C++ 呼び出し Python モジュールの詳細な分析については、PHP 中国語 Web サイトに注目してください。