When processing Python objects in C/C ++, correct maintenance of the reference count is a key issue. If it is not handled properly, memory leakage may occur. Python's C language interface provides some macros to maintain the reference count. The most common is to use py_incref () to increase the reference count of Python objects by 1, and use py_decref () to reduce the reference count of Python objects by 1.
2.3 Data Type
Python defines six data types: integer, floating point, String, tuples, lists, and dictionaries, first, you need to know how to convert data types in C and python.
2.3.1 integer, floating point, and string
It is relatively simple to use integer, floating point, and string data types in Python C Language extension. You only need to know how to generate and maintain them. The following example shows how to use python in C:
Example 2: typeifs. C // build an integerpyobject * pint = py_buildvalue ("I", 2003); Assert (pyint_check (pint); int I = pyint_aslong (pint); py_decref (pint ); // build a floatpyobject * pfloat = compile ("F", 3.14f); Assert (pyfloat_check (pfloat); float F = pyfloat_asdouble (pfloat); py_decref (pfloat ); // build a stringpyobject * pstring = py_buildvalue ("S", "Python"); Assert (pystring_check (pstring); int nlen = pystring_size (pstring ); char * s = pystring_asstring (pstring); py_decref (pstring ); |
2.3.2 tuples
The tuples In the Python language are fixed-length arrays. When the python interpreter calls methods in the C language extension, all non-Keyword parameters are transmitted as tuples. The following example demonstrates how to use Python's tuples in C:
Example 3: typetuple. C // create the tuplepyobject * ptuple = pytuple_new (3); Assert (pytuple_check (ptuple); Assert (pytuple_size (ptuple) = 3 ); // set the values (ptuple, 0, py_buildvalue ("I", 2003); values (ptuple, 1, py_buildvalue ("F", 3.14f); pytuple_setitem (ptuple, 2, py_buildvalue ("S", "Python"); // parse tuple itemsint I; float F; char * s; If (! Pyarg_parsetuple (ptuple, "ifs", & I, & F, & S) pyerr_setstring (pyexc_typeerror, "invalid parameter"); // cleanuppy_decref (ptuple ); |
2.3.3 list
The list in python is a variable-length array. The list is more flexible than the tuples. You can use the list to randomly access the python objects stored in it. The following example demonstrates how to use the python list type in the C language:
Example 4: typelist. C // create the listpyobject * plist = pylist_new (3); // new referenceassert (pylist_check (plist); // set some initial valuesfor (INT I = 0; I <3; ++ I) pylist_setitem (plist, I, py_buildvalue ("I", I); // insert an itempylist_insert (plist, 2, py_buildvalue ("S ", "inserted"); // append an itempylist_append (plist, py_buildvalue ("S", "appended"); // sort the listpylist_sort (plist ); // reverse the listpylist_reverse (plist); // fetch and manipulate a list slicepyobject * pslice = pylist_getslice (plist, 2, 4); // new referencefor (Int J = 0; j <pylist_size (pslice); ++ J) {pyobject * pvalue = pylist_getitem (plist, J); Assert (pvalue);} py_decref (pslice ); // cleanuppy_decref (plist ); |
2.3.4 dictionary
The dictionary in python is a data type accessed Based on keywords. The following example demonstrates how to use the python dictionary type in the C language:
Example 5: typedic. C // create the dictionarypyobject * pdict = pydict_new (); // new referenceassert (pydict_check (pdict); // Add a few named valuespydict_setitemstring (pdict, "first ", py_buildvalue ("I", 2003); pydict_setitemstring (pdict, "second", py_buildvalue ("F", 3.14f )); // enumerate all named valuespyobject * pkeys = pydict_keys (); // new referencefor (INT I = 0; I <pylist_size (pkeys); ++ I) {pyobject * pkey = pylist_getitem (pkeys, I); pyobject * pvalue = pydict_getitem (pdict, pkey); Assert (pvalue);} py_decref (pkeys ); // remove a named valuepydict_delitemstring (pdict, "second"); // cleanuppy_decref (pdict ); |
Iii. Python C Language extension
3.1 Module Encapsulation
After learning about the C language interfaces of Python, you can use these interfaces provided by the python interpreter to compile C language extensions of Python. Assume that the following C language functions are supported:
Example 6: example. CINT fact (int n) {If (n <= 1) return 1; else return N * fact (n-1 );} |
This function is used to calculate the factorial of a given natural number. If you want to call this function in the python interpreter, you should first implement it as a module in Python, you need to write the corresponding encapsulation interface as follows:
Example 7: Wrap. C # include <python. h> pyobject * wrap_fact (pyobject * Self, pyobject * ARGs) {int N, result; If (! Pyarg_parsetuple (ARGs, "I: Fact", & N) return NULL; Result = fact (n); Return py_buildvalue ("I", result );} static pymethoddef examplemethods [] = {"fact", wrap_fact, meth_varargs, "caculate n! "},{ Null, null }}; void initexample () {pyobject * m; M = py_initmodule (" example ", examplemethods );} |
A typical Python extension module consists of at least three parts: the export function, method list, and initialization function.
3.2 export functions
To use a function in C language in the python interpreter, you must first compile the corresponding export function for it. In the preceding example, the export function is wrap_fact. In Python C language extensions, all exported functions have the same function prototype:
PyObject* method(PyObject* self, PyObject* args);
This function is an interface between the python interpreter and the C function. It has two parameters: Self and args. The self parameter is used only when the C function is implemented as an inline method (built-in method). Generally, the value of this parameter is null ). The args parameter contains all the parameters that the python interpreter must pass to the C function. The Python C Language extension interface provides the pyarg_parsetuple () function to obtain these parameter values.
All export functions return a pyobject pointer. If the corresponding C function does not return a real value (that is, the return value type is void), a global none object (py_none) should be returned ), add the reference count to 1, as shown below:
PyObject* method(PyObject *self, PyObject *args) { Py_INCREF(Py_None); return Py_None;} |
3.3 method list
The method list shows all the methods that can be used by the python interpreter. The method list corresponding to the above example is:
static PyMethodDef exampleMethods[] = { {"fact", wrap_fact, METH_VARARGS, "Caculate N!"}, {NULL, NULL}}; |
Each item in the method list consists of four parts: method name, export function, parameter transfer method, and method description. The method name is the name used to call this method from the python interpreter. The parameter passing method specifies the specific form of passing parameters to the C function in Python. The two optional methods are meth_varargs and meth_keywords. meth_varargs is the standard form of parameter passing, it uses the python tuples to pass parameters between the python interpreter and the C function. If meth_keyword is used, then, the python interpreter and the C function will pass parameters between the two through the python dictionary type.
3.4 initialization Function
All Python extension modules must have an initialization function so that the python interpreter can correctly initialize the module. The Python interpreter specifies that the names of all initialization functions must start with init and add the module name. For the module example, the corresponding initialization function is:
void initexample() { PyObject* m; m = Py_InitModule("example", exampleMethods);} |
When the python interpreter needs to import the module, it will find the corresponding initialization function based on the module name. Once it is found, it will call the function for initialization, the initialization function registers all the methods available in this module with the python interpreter by calling the function py_initmodule () provided by the python C Language extension interface.
3.5 compilation Link
To use an extension module written in C language in the python interpreter, it must be compiled into a dynamic link library. The following uses RedHat Linux 8.0 as an example to describe how to compile the python extension module compiled in C into a dynamic link library:
[xiaowp@gary code]$ gcc -fpic -c -I/usr/include/python2.2 \ -I /usr/lib/python2.2/config \ example.c wrapper.c[xiaowp@gary code]$ gcc -shared -o example.so example.o wrapper.o |
3.6 introduce the python Interpreter
After the dynamic link library of the python extension module is generated, you can use the extension module in the python interpreter. This is the same as the python built-in module, the extension module is also used after being introduced through the import Command, as shown below:
[xiaowp@gary code]$ pythonPython 2.2.1 (#1, Aug 30 2002, 12:15:30)[GCC 3.2 20020822 (Red Hat Linux Rawhide 3.2-4)] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import example>>> example.fact(4)24>>> |
> Import foo
> Foo. Bar ('123 ')
5
If you think you have learned how to compile something that can be used in Python, you will not waste your precious time reading it. Instead, you will give me a look of contempt: that's a simple question.
The following is an example: in my Linux section, I have <Linux dynamic link library programming introduction>.
/* Foomain. C */
# Include <python2.4/python. h>
/* Define the method table .*/
Static pyobject * foo_BAR (pyobject * Self, pyobject * ARGs );
Static pymethoddef foomethods [] = {
{"Bar", foo_BAR, meth_varargs },
{Null, null}
};
/* Here's the initialization function. We don't need to do anything
* For our own needs, but Python needs that method table .*/
Void initfoo ()
{
(Void) py_initmodule ("foo", foomethods );
}
/* Finally, let's do something... involved... as an example function .*/
Static pyobject * foo_BAR (pyobject * Self, pyobject * ARGs)
{
Char * string;
Int Len;
If (! Pyarg_parsetuple (ARGs, "S", & string ))
Return NULL;
Len = strlen (string );
Return py_buildvalue ("I", Len );
}
Run gcc-FPIC-shared-O Foo. So foomain. C in Linux.
The "foo. So" file will appear in the current directory.