How to use C ++ to expand Python Functions
This article focuses on how to use C ++ to extend Python functions.
Environment
VS2005Python2.5.4Windows7 (32-bit)
Introduction
To put it short, the Python Extension function mentioned here is a little different from writing a dynamic link library directly in other languages and then calling Python (though essentially the same ). It refers to the use of the APIS provided by Python and the use of C ++ for Functional extension of Python, use a more efficient language to implement some algorithm computing and other modules that require higher execution efficiency (or that require close interaction with the system, it sounds attractive to let Python call these modules like calling the built-in standard library ?! Today, with the rapid development of software technology, there are countless examples of a system using several computer languages. The goal is to balance performance and convenience. For example, the use of C ++ to expand Python discussed in this article is a clever combination of Python and C ++. The advantages are self-evident, it can achieve similar execution performance as C ++ and utilize the development flexibility of Python. Since Python itself is implemented in C, it is easier to combine the two.
Basic Process
This article is not suitable for readers who have no knowledge of Python or C \ C ++. There are six basic data types in Python. You need to know how to convert these types between C and Python (this is not covered in this article, refer to [1]).
Back to the truth, I feel that I have mentioned too much. In fact, it is very simple, so I decided to do more. A c ++ Python extension module should have at least three parts: Export function, method list and initialization function. We use VS2005, a powerful tool! In general, you should build a Dll Project (it is not possible to use exe to expand Python, but it has not been studied yet ). The following step-by-step description (the key description is in the remarks section ).
I. initialization functions
// Functions // function: initPyExt // function: initialization function // return value: PyMODINIT_FUNC // Note: The name of this function cannot be changed. It must be the init + Module name, // Our Module name is PyExt, so the function name is initPyExt. Python finds this function and calls it when importing // Our PyExt module. The // function implemented by this function is very simple. By calling Py_InitModule, you can combine the module name with the ing table //. It means that the PyExt module uses the ing table PyExtMethods. // --------------------------------------------------------------------------- PyMODINIT_FUNCinitPyExt () {Py_InitModule ("PyExt", PyExtMethods );}
Ii. Method list
/* Method list. This is a C-structure array. Map all the functions to be extended to this table. Then Python will know what methods your extension module supports. The first field of the table is the method name, which is also the name used for calling through Python. The second field is the export function, which is the actually called function and the function implemented by C \ C ++. The third parameter indicates the form in which Python Passes parameters to the C \ C ++ function. Two optional methods are METH_VARARGS and METH_KEYWORDS. METH_VARARGS is the standard form of parameter passing. It passes parameters between the Python interpreter and the C function through the Python tuples, if METH_KEYWORD is used, parameters are transmitted between the Python interpreter and the C function through the Python dictionary type. The fourth field is the description of this function. If you help this function in python, this description will be displayed. It is equivalent to the description of functions in python. */StaticPyMethodDefPyExtMethods [] = {"Add", Add, METH_VARARGS, "Addtwo number-edit by magictong. "},{" ExecSystem ", ExecSystem, METH_VARARGS," Execute a shell command-edit bymagictong. "},{ NULL, NULL, 0, NULL }};
Iii. Export Functions
// Functions // function: Add // function: This is an addition function // return value: PyObject * // parameter: PyObject * self this parameter is ignored temporarily // parameter: pyObject * args is a parameter list from which we need to parse the parameter // Note: // all export functions share the same prototype: // PyObject * method (PyObject * self, PyObject * args); // PyArg_ParseTuple to complete the Parameter Parsing task. Its first parameter is args, and // is the parameter to be converted. The second is the format symbol. "S" indicates a string. // Extract a parameter from args and write "s". For two parameters, write "s | s". If it is a // string or an int, write "s | I", which is a bit similar to printf. The third parameter is the true location of the extracted parameter. The address of this parameter must be passed. // Declare staticPyObject * Add (PyObject * self, PyObject * args) {intx = 0; inty = 0; intz = 0; if (! PyArg_ParseTuple (args, "I | I", & x, & y) returnNULL; z = x + y; returnPy_BuildValue ("I", z ); /* after the call, we need to return the result. The result is the type of c or the type defined by ourselves. He must be converted to PyObject to let python know. This is done using Py_BuildValue. It is the inverse process of PyArg_ParseTuple. The first parameter is the same as the second parameter of PyArg_ParseTuple. It is a formatting symbol. The third parameter is the parameter to be converted. Py_BuildValue assembles all the returned results into one tutple for python. If the corresponding C function has no return value (that is, the return value type is void), a global None object (Py_None) should be returned and Its Reference count should be increased, as shown below: py_INCREF (Py_None); returnPy_None ;*/}
4. Add more features
intcmd(constchar* arg){ returnsystem(arg);} staticPyObject*ExecSystem(PyObject*self,PyObject*args){ constchar*command; if(!PyArg_ParseTuple(args,"s", &command)) returnNULL; intn =cmd(command); returnPy_BuildValue("i",n);}
Compile
Compile and compile PyExt. the dll file is renamed to PyExt. put pyd In the Python C: \ Python25 \ DLLs directory and you can use it globally. If you only want a Python project, put it under the relative path of the project.
Use
Possible problems
Where are the macros and definitions related to Python in PyMODINIT_FUNC? You can define # include <Python. h>, but after the definition is completed, the system prompts that Python. h cannot be found or compilation is not enough. What should I do? This indicates that you have not installed Python or installed Python, but have not introduced the header file Path to the Path environment variable, or you have added the include directory of Python to the Additional include directory (Additional IncludeDirectories) of the project ), this is generally the C: \ Python25 \ include directory, where C: \ Python25 is the Python installation directory, which is configured according to your machine's actual situation ).
If the Error message is: error 1 fatal Error LNK1104: cannot open file 'python25 _ d. lib 'errors similar to this may be caused by the absence of Python development version. It doesn't matter. Use Release to compile it. If not, set C: add the \ Python25 \ libs directory to the project's Additional library directory (Additional LibraryDirectories ).
Summary
The above is all the details about how to use C ++ to extend Python functions. I hope it will be helpful to you. If you are interested, you can continue to refer to other related topics on this site. If you have any shortcomings, please leave a message. Thank you for your support!