Home > Backend Development > PHP Tutorial > Calling relationship between C/Python_PHP tutorial

Calling relationship between C/Python_PHP tutorial

WBOY
Release: 2016-07-12 08:54:03
Original
877 people have browsed it

Calling relationship between C/Python

Since python has many powerful open source libraries, c can borrow methods from them to complete more functions.

Therefore, the method of calling python from C is particularly important.

Method/Steps

  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 source file]: 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("please input 2 args!!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);

    printf("%d %d = %ldn",arg0,arg1,PyInt_AsLong(pRetValue));


    Py_DECREF(pModule);

    Py_DECREF(pFunction);

    Py_DECREF(pArgs);

    Py_DECREF(pRetValue);


    Py_Finalize();

    return 0;

    }

  3. 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() function in Python extension

    The role of Py_BuildValue() function is opposite to that of PyArg_ParseTuple(). It converts C type data structure into a Python object. The prototype of this function is: PyObject *Py_BuildValue(char *format, ...) This function can recognize a series of format strings like the PyArg_ParseTuple() function, but the input parameters can only be values, not pointers. It returns a Python object. The difference from PyArg_ParseTuple() is that the first parameter of the PyArg_ParseTuple() function is a tuple, while Py_BuildValue() does not necessarily generate a tuple. It generates a tuple only if the format string contains two or more format units, and returns NONE if the format string is empty. In the following description, the item in brackets is the type of the Python object returned by the format unit, and the item in square brackets is the type of the C value passed. "s" (string) [char *]: Convert a C string into a Python object. If the C string is empty, return NONE. "s#" (string) [char *, int]: Convert a C string and its length into a Python object. If the C string is a null pointer, the length is ignored and NONE is returned. "z" (string orNone) [char *]: The same as "s". "z#" (string orNone) [char *, int]: The function is the same as "s#". "i" (integer) [int]: Convert a C type int into a Python int object. "b" (integer) [char]: Same as "i". "h" (integer) [short int]: The function is the same as "i". "l" (integer) [long int]: Convert C type long to int object in Pyhon. "c" (string of length 1) [char]: Convert C type char into a Python string object of length 1. "d" (float) [double]: Convert C type double to a floating point object in python. "f" (float) [float] :The function is the same as "d". "O&" (object) [converter,anything]: Convert any data type into a Python object through the conversion function. The data is called as a parameter of the conversion function and returns a new Python object if an error occurs. Return NULL. "(items)" (tuple) [matching-items] : Convert a series of C values ​​into Python tuples. "[items]" (list) [matching-items] : Convert a series of C values ​​into a Python list. "{items}" (dictionary) [matching-items]: Convert a series of C values ​​into a Python dictionary. Each pair of consecutive C values ​​will be converted into a key-value pair.
    For example: Py_BuildValue("") None Py_BuildValue("i", 123) 123 Py_BuildValue("iii", 123, 456, 789) (123, 456, 789) Py_BuildValue("s" , "hello") 'hello' Py_BuildValue("ss", "hello", "world") ('hello', 'world') Py_BuildValue("s#", "hello", 4) 'hell' 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))

    In-depth analysis of C calling Python module





    Python provides a C library that allows developers to easily call Python modules from C programs. Next, through this article, I will introduce you to the relevant knowledge of C calling Python modules. Friends who need it can refer to it

    Generally, those who have developed games know that Lua and C can be well combined, learn from each other's strengths, and treat Lua scripts as similar dynamics. Link libraries are used to make good use of the flexibility of script development. As a popular general-purpose scripting language, Python can also do it. In a C application, we can use a set of plug-ins to implement some functions with a unified interface. Generally, plug-ins are implemented using dynamic link libraries. If plug-ins change frequently, we can use Python instead of dynamic link libraries. Plug-ins (which can be called dynamic link libraries in text form) make it easy to rewrite script code according to changing needs, instead of having to recompile and link binary dynamic link libraries. Flexibility is greatly improved.

    As a glue language, Python can easily call C, C and other languages, and can also call Python modules through other languages.

    Python provides a C library that allows developers to easily call Python modules from C programs.

    For specific documentation, please refer to the official guide:

    Embedding Python in Another Application

    Call method

    1 Link to Python calling library

    The Python installation directory already contains header files (include directory) and library files (python27.lib under Windows).

    You need to link to this library before using it.

    2 Directly call the Python statement

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

    3 Load the Python module and call the function

    ~/test directory contains test.py:

    <code class="language-python hljs ">def test_add(a, b):print 'add ', a, ' and ', breturn a+b</code>
    Copy after login

    You can call the test_add function through the following 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>
    Copy after login

    Parameter passing

    1 C Passing parameters to Python

    Python’s parameters are actually tuples, so Passing parameters is actually constructing a suitable tuple.

    There are two commonly used methods:

    Use PyTuple_New to create tuples, PyTuple_SetItem to set tuple values

    <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>
    Copy after login

    Use Py_BuildValue directly to construct tuples

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

    Format strings such as i, s, f can refer to format string

    2 Convert Python return value

    What you get when calling Python are PyObject objects, so you need to use Python Some functions in the provided library convert the return value to C, such as PyInt_AsLong, PyFloat_AsDouble, PyString_AsString, etc.

    You can also use the PyArg_ParseTuple function to parse the return value as a tuple.

    PyArg_Parse is also a conversion function that is very convenient to use.

    PyArg_ParseTuple and PyArg_Parse both use format strings

    Notes

    You need to switch the Python working directory to the path where the module is located. Load the module according to the module name instead of the file name or Function loading needs to be verified successfully, otherwise it may cause a stack error and cause the program to crash. Py_DECREF(PyObject*) needs to be used to dereference the object (for Python garbage collection)

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1121870.htmlTechArticleThe calling relationship between C and Python. Since python has many powerful open source libraries, c can borrow methods from them. Complete more functions. Therefore, the method of calling python from C is particularly important. Method...
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template