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 = % ld \ n", arg0, arg1, PyInt_AsLong (pRetValue ));
Py_DECREF (pModule );
Py_DECREF (pFunction );
Py_DECREF (pArgs );
Py_DECREF (pRetValue );
Py_Finalize ();
Return 0;
}
3Root @ 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 the Py_BuildValue () function is opposite to that of PyArg_ParseTuple (). It converts a C-type data structure to a Python object. the prototype of this function is as follows: pyObject * Py_BuildValue (char * format ,...) this function can recognize a series of format strings like PyArg_ParseTuple (), but the input parameter can only be a value, not a pointer. It returns a Python object. Unlike PyArg_ParseTuple (), the first parameter of the PyArg_ParseTuple () function is a tuples. Py_BuildValue () does not necessarily generate a tuple. It generates a single tuples. only when the format string contains two or more format units, if the format string is empty, the return value is NONE. In the following description, the items in the brackets are the type of Python object returned by the format unit, and the items in the square brackets are the type of the value of the passed C. "S" (string) [char *]: converts a C string to a Python object. if the C string is null, NONE is returned. "S #" (string) [char *, int]: converts the C string and its length to a Python object. if the C string is a null pointer and the length is ignored, NONE is returned. "Z" (string orNone) [char *]: same as "s "."Z #" (string orNone) [char *, int]: same as "s #"."I" (integer) [int]: converts a C-type int to a Python int object. "B" (integer) [char]: same as "I ". "H" (integer) [short int]:The same role as "I ". "L" (integer) [long int]: converts a long of the C type to an int object in Pyhon. "C" (string of length 1) [char]: converts a C-type char to a Python string object with a length of 1. "D" (float) [double]: converts a double of the C type to a floating point object in python. "F" (float) [float]:The function is the same as "d ". "O &" (object) [converter, anything]: converts any data type to a Python object through a conversion function, the data is called as a parameter of the conversion function and a new Python object is returned. If an error occurs, NULL is returned. "(Items)" (tuple) [matching-items]: converts a series of C values into Python Tuples. "[Items]" (list) [matching-items]: converts a series of C values into a Python list. "{Items}" (dictionary) [matching-items]: converts the C value of a series of classes into a Python dictionary, each successive C value is converted into a key-value pair.
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)", 1, 2, 3, 4, 5, 6) (1, 2), (3, 4), (5, 6 ))
In-depth analysis of C ++ calling the Python module
Python provides a C ++ library, allowing developers to conveniently call the Python module from a C ++ program. Next, I will introduce you to the C ++ Python module through this article. For more information, see.
Generally, those who have developed games know that Lua and C ++ can be well combined to learn from each other and use Lua scripts as similar dynamic link libraries. This makes good use of the flexibility of script development. As a popular general scripting language, Python can also be used. In a C ++ application, we can use a set of plug-ins to implement functions with unified interfaces. generally, plug-ins are implemented using dynamic link libraries. if the plug-ins change frequently, we can use Python to replace the plug-in the form of dynamic link library (a text-style dynamic link library), so that we can easily rewrite the script code as needed, instead of re-compiling the dynamic link library that links binary data. The flexibility is greatly improved.
As a glue language, Python can easily call C, C ++, and other languages. It can also call Python modules in other languages.
Python provides a C ++ library, allowing developers to conveniently call the Python module from a C ++ program.
For specific documents, refer to the official guide:
Embedding Python in Another Application
Call method
1. link to the Python call Library
The Python installation directory contains the header file (include directory) and library file (python27.lib in Windows ).
You need to link to this library before using it.
2. directly call the Python statement
# Include "python/Python. h" int main () {Py_Initialize (); # Initialize PyRun_SimpleString ("print 'hello'"); Py_Finalize (); # release resources}
3. load the Python module and call functions
~ The/test directory contains test. py:
def test_add(a, b):print 'add ', a, ' and ', breturn a+b
Use the following code to call the test_add function:
# Include "python/Python. h" # include Using namespace std; int main () {Py_Initialize (); // initialize // switch the Python working path to the directory where the module to be called is located. ensure that the path name is correct. string path = "~ /Test "; string chdir_cmd = string (" sys. path. append (\ "") + path + "\") "; const char * cstr_cmd = chdir_1_.c_str (); PyRun_SimpleString (" import sys "); PyRun_SimpleString (cstr_cmd ); // load the module PyObject * moduleName = PyString_FromString ("test"); // The module name, not the file name PyObject * pModule = PyImport_Import (moduleName); if (! PModule) // failed to load the module {cout <"[ERROR] Python get module failed. "<endl; return 0 ;}cout <" [INFO] Python get module succeed. "<endl; // load function PyObject * pv = PyObject_GetAttrString (pModule," test_add "); if (! Pv |! PyCallable_Check (pv) // verify whether the load is successful {cout <"[ERROR] Can't find funftion (test_add)" <endl; return 0 ;} cout <"[INFO] Get function (test_add) succeed. "<endl; // Set the PyObject * args = PyTuple_New (2); // two parameters: PyObject * arg1 = PyInt_FromLong (4 ); // Set parameter 1 to 4PyObject * arg2 = PyInt_FromLong (3); // Set parameter 2 to 3PyTuple_SetItem (args, 0, arg1); PyTuple_SetItem (args, 1, arg2 ); // call the function PyObject * pRet = PyObject_CallObject (pv, args); // Obtain the parameter if (pRet) // verify whether the call is successful {long result = PyInt_AsLong (pRet ); cout <"result:" <result;} Py_Finalize () ;## Release resource return 0 ;}
Parameter transfer
1 C ++ pass parameters to Python
Python parameters are actually tuples, so passing parameters is actually to construct a suitable tuple.
There are two common methods:
Use PyTuple_New to create a tuples, and set the values of the tuples in PyTuple_SetItem.
PyObject * args = PyTuple_New (3); PyObject * arg1 = Py_BuildValue ("I", 100); // The integer parameter PyObject * arg2 = Py_BuildValue ("f", 3.14 ); // floating point number parameter PyObject * arg3 = Py_BuildValue ("s", "hello"); // string parameter PyTuple_SetItem (args, 0, arg1); PyTuple_SetItem (args, 1, arg2); PyTuple_SetItem (args, 2, arg3 );
Directly use Py_BuildValue to construct the tuples
PyObject * args = Py_BuildValue ("ifs", 100, 3.14, "hello"); PyObject * args = Py_BuildValue ("()"); // no parameter function
For formats such as I, s, and f, refer to format strings.
2. convert the Python return value
Python is called to obtain all PyObject objects. Therefore, you need to use some functions in the library provided by Python to convert the returned values to C ++, such as PyInt_AsLong, PyFloat_AsDouble, and PyString_AsString.
You can also use the PyArg_ParseTuple function to parse the returned values as tuples.
PyArg_Parse is also a convenient conversion function.
Both PyArg_ParseTuple and PyArg_Parse use format strings.
Notes
You need to switch the Python working directory to the module path and load the module by the module name instead of the file name module or function load to verify whether the module is successful, otherwise, the program may crash due to a stack error. you need to use Py_DECREF (PyObject *) to remove the reference of the object (for Python garbage collection)