ホームページ > バックエンド開発 > PHPチュートリアル > C/Python_PHP間の呼び出し関係チュートリアル

C/Python_PHP間の呼び出し関係チュートリアル

WBOY
リリース: 2016-07-12 08:54:03
オリジナル
872 人が閲覧しました

C/Python 間の呼び出し関係

Python には強力なオープンソース ライブラリが多数あるため、C はそれらのライブラリからメソッドを借用して、より多くの関数を完成させることができます。

そのため、CからPythonを呼び出す方法は特に重要です。

方法/手順

  1. ubuntu 14.04 linux c

    gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

    Python 2.7.6

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

    root@linux:~/code# gcc -o c_call_python c_call_python.c -lpython2.7

    root@linux:~/code# ./c_call_python 12 15

    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>
    ログイン後にコピー

    3 Python モジュールをロードして関数を呼び出します

    ~/test ディレクトリには test.py:

    <code class="language-python hljs ">def test_add(a, b):print 'add ', a, ' and ', breturn 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); // 参数一设为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>
    ログイン後にコピー

    パラメータの受け渡し

    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 などの書式文字列の場合は、フォーマット文字列を参照できます

    2 Python の戻り値を変換する

    Python を呼び出したときに取得するものは PyObject オブジェクトであるため、戻り値を C++ に変換するには、Python が提供するライブラリ内の関数 (PyInt_AsLong など) を使用する必要があります。 PyFloat_AsDouble、PyString_AsString など

    PyArg_ParseTuple 関数を使用して、戻り値をタプルとして解析することもできます。

    PyArg_Parse も非常に便利な変換関数です。

    PyArg_ParseTuple と PyArg_Parse は両方ともフォーマット文字列を使用します

    注意事項

    モジュールのロードまたは関数のロードでは、ファイル名ではなくモジュール名に従って Python 作業ディレクトリを切り替える必要があります。成功したかどうかを確認します。そうでない場合は、スタックが発生する可能性があります。エラーによりプログラムがクラッシュします。オブジェクトを逆参照するには、Py_DECREF(PyObject*) を使用する必要があります (Python ガベージ コレクション用)。

    www.bkjia.com本当http://www.bkjia.com/PHPjc/1121870.html技術記事 C/Python 間の呼び出し関係 Python には強力なオープンソース ライブラリが多数あるため、C はそれらのライブラリからメソッドを借用して、より多くの関数を完成させることができます。 したがって、CからPythonを呼び出す方法は特に重要です。 方法...

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート