Python には強力なオープンソース ライブラリが多数あるため、C はそれらのライブラリからメソッドを借用して、より多くの関数を完成させることができます。
そのため、CからPythonを呼び出す方法は特に重要です。
ubuntu 14.04 linux c
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Python 2.7.6
file 1 [python file]: math_test.py
def add_func(a,b):
return a+b
def sub_func(a,b):
return (a-b)
file 2 [c ソースファイル]: c_call_python。 c
#include
#include
#include
#include "python2.7/Python.h"
int main(int argc, char** argv)
{
int arg0 = 0,arg1 = 0;
if(argc == 3){
arg0 = atoi(argv[1]);
arg1 = atoi(argv[2]);
}else {
printf("引数を 2 つ入力してください!!n");
return -1;
}
Py_Initialize();
if ( !Py_IsInitialized())
return -1;
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pModule;
PyObject *pFunction;
PyObject *pArgs;
PyObject * pRetValue;
pModule = PyImport_ImportModule("math_test");
if(!pModule){
printf("import Python failed!!n");
return -1;
}
pFunction = PyObject_GetAttrString(pModule, "add_func");
if(!pFunction){
printf("get Python function failed!!!n");
return -1;
}
pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", arg0));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", arg1));
pretvalue = pyobject_callobject(pfunction、pargs); );
Py_DECREF(pArgs);
Py_DECREF(pRetValue);
Py_Finalize();
return 0;
}
3
12 + 15 = 27
Py_BuildValue() 関数 (Python 拡張機能)
Py_BuildValue() 関数は、C 型のデータ構造を Python オブジェクトに変換します: PyObject *Py_BuildValue。 (char *format, ...) この関数は、PyArg_ParseTuple() 関数と同様に一連のフォーマット文字列を識別できますが、入力パラメーターは値のみであり、ポインターは使用できません。 Python オブジェクトを返します。 PyArg_ParseTuple() との違いは、PyArg_ParseTuple() 関数の最初のパラメーターがタプルであるのに対し、Py_BuildValue() は必ずしもタプルを生成しないことです。書式文字列に 2 つ以上の書式単位が含まれる場合にのみタプルを生成し、書式文字列が空の場合は NONE を返します。 次の説明では、括弧内の項目はフォーマット ユニットによって返される Python オブジェクトの型であり、角括弧内の項目は渡される C 値の型です。 "s" (string) [char *]: C 文字列を Python オブジェクトに変換します。C 文字列が空の場合は、NONE を返します。 "s#" (string) [char *, int]: C 文字列とその長さを Python オブジェクトに変換します。C 文字列が null ポインターの場合、長さは無視され、NONE が返されます。 "z" (文字列 orNone) [char *]: "s" と同じ。 "z#" (string orNone) [char *, int]: 機能は "s#" と同じです。 "i" (整数) [int]: C 型の int を Python int オブジェクトに変換します。 "b" (整数) [char]: "i" と同じ。 "h" (integer) [short int]: 機能は "i" と同じです。 "l" (integer) [long int]: Pyhon で C 型の long を int オブジェクトに変換します。 "c" (長さ 1 の文字列) [char]: C 型の char を長さ 1 の Python 文字列オブジェクトに変換します。 "d" (float) [double]: C 型の double を Python の浮動小数点オブジェクトに変換します。 "f" (float) [float] :機能は "d" と同じです。 "O&" (object) [converter,anything]: 変換関数を通じて任意のデータ型を Python オブジェクトに変換します。データは変換関数のパラメーターとして呼び出され、エラーが発生した場合は新しい Python オブジェクトが返されます。 , NULL が返されます。 "(items)" (tuple) [matching-items] : 一連の C 値を Python タプルに変換します。 "[items]" (list) [matching-items] : 一連の C 値を Python リストに変換します。 "{items}" (dictionary) [matching-items]: 一連の C 値を Python 辞書に変換します。連続する C 値の各ペアがキーと値のペアに変換されます。
例: Py_BuildValue("") なし Py_BuildValue("i", 123) 123 Py_BuildValue("iii", 123, 456, 789) (123, 456, 789) Py_BuildValue("s", "hello") ' こんにちは' Py_BuildValue("ss", "hello", "world") ('hello', 'world') Py_BuildValue("s#", "hello", 4) '地獄' Py_BuildValue("()" ) () Py_BuildValue("(i)", 123) (123,) Py_BuildValue("(ii)", 123, 456) (123, 456) Py_BuildValue("(i,i)", 123, 456) ( 123 , 456) Py_BuildValue("[i,i]", 123, 456) [123, 456] Py_BuildValue("{s:i,s:i}","abc", 123, "def", 456) { ' abc': 123, 'def': 456} Py_BuildValue("((ii)(ii)) (ii)",1, 2, 3, 4, 5, 6) (((1, 2), (3) 、4))、(5, 6))Pythonモジュールを呼び出すC++の詳細な分析
Python は、開発者が C++ プログラムから Python モジュールを簡単に呼び出せるようにする C++ ライブラリを提供します。次に、この記事を通じて、Python モジュールを呼び出す C++ の関連知識を紹介します。一般に、ゲームを開発したことがある人は、Lua と C++ をうまく組み合わせて学習できることを知っています。 、Lua スクリプトをダイナミック リンク ライブラリと同様に扱い、スクリプト開発の柔軟性をうまく活用します。人気の汎用スクリプト言語である Python でもそれが可能です。 C++ アプリケーションでは、プラグインのセットを使用して、統一されたインターフェイスを持ついくつかの機能を実装できます。通常、プラグインが頻繁に変更される場合は、プラグインの代わりに Python を使用できます。ダイナミック リンク ライブラリ形式。プラグイン (テキスト形式ではダイナミック リンク ライブラリと呼ぶこともできます) を使用すると、バイナリ ダイナミック リンク ライブラリを再コンパイルしてリンクする必要がなく、ニーズの変化に応じてスクリプト コードを簡単に書き直すことができます。柔軟性が大幅に向上します。 Python はグルー言語として、C、C++、その他の言語を簡単に呼び出すことができ、また、他の言語を通じて Python モジュールを呼び出すこともできます。 Python は C++ ライブラリを提供しており、開発者は C++ プログラムから Python モジュールを簡単に呼び出すことができます。 特定のドキュメントについては、公式ガイドを参照してください: 別のアプリケーションへの Python の埋め込みメソッドの呼び出し1 Python 呼び出しライブラリへのリンク Python インストール ディレクトリには、ヘッダー ファイル (インクルード ディレクトリ) とライブラリ ファイル (python27) がすでに含まれていますWindows の場合) .lib)。 このライブラリを使用する前に、このライブラリにリンクする必要があります。 2 Python ステートメントを直接呼び出します<code class="language-cpp hljs ">#include "python/Python.h"int main(){Py_Initialize(); ## 初始化PyRun_SimpleString("print 'hello'");Py_Finalize(); ## 释放资源}</code>
<code class="language-python hljs ">def test_add(a, b):print 'add ', a, ' and ', breturn a+b</code>
<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); // 参数一设为4PyObject* arg2 = PyInt_FromLong(3); // 参数二设为3PyTuple_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>
<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>
<code class="language-cpp hljs ">PyObject* args = Py_BuildValue("ifs", 100, 3.14, "hello");PyObject* args = Py_BuildValue("()"); // 无参函数</code>