Development environment: ubuntu9.10,python2.6,gcc4.4.1
The Python run package and the development package under 1,ubuntu are separate, so you need to install Python-all-dev inside the new profit, so you can reference Python's header files and libraries in your code.
2. Here is one of the simplest C extension modules that can be called by Python, assuming that the C program file is named FOO.C:
Code#include <Python.h>
Static pyobject* Foo_bar (pyobject* self, pyobject* args) {
Py_return_none;
}
Static Pymethoddef foo_methods[] = {
{"Bar", (pycfunction) Foo_bar,meth_noargs,null},
{Null,null,0,null}
};
Pymodinit_func Initfoo () {
Py_initmodule3 ("foo", Foo_methods, "My first extension module.");
}
We can divide the above module into 3 parts: 1) C module to expose the external interface function. 2) provides a C module Function name Mapping table used by the external Python program. 3) The initialization function of the C module. The first line of the module, Python.h, is introduced into the module, which will allow your module to hook into the Python interpreter so that it can be used by external Python programs.
function signatures in C modules generally have the following three types:
pyobject* MyFunction (pyobject* self, pyobject* args);
pyobject* Myfunctionwithkeywords (pyobject* self, pyobject* args, pyobject* kw);
pyobject* Myfunctionwithnoargs (pyobject* self);
In general, we use the first method, the parameters of the function will be passed in a tuple (tuple), so we need to parse it in the function of the C module. Python cannot declare a void type function like C, and if you don't want the function to return a value, return a none, which we can do with a macro py_return_none in the Python header file.
The name of the function in the C module is actually invisible to the outside, so you can name it, so we can use the static function (which is not visible outside the current file in the C language). The function naming method uses the module name plus the function name, such as Foo_bar, which means that there will be a bar function in the module FOO. Then there is the function mapping table, which is an array of pymethoddef structures,
struct Pymethoddef {
char* Ml_name;
Pycfunction Ml_meth;
int ml_flags;
char* Ml_doc;
};
The first member, Ml_name, is the function name, which is used to make function calls when we use this module in external Python code. Ml_meth is the function address. Ml_flags tells the interpreter which Ml_meth will use the above three methods to sign, generally set to Meth_varargs, and if you want to allow the keyword argument, you can do it with meth_keywords. If you do not want to accept any parameters, you can set it to Meth_noargs. Finally, the Ml_doc field is a function of the comment document information, it is best to write a few words, otherwise it will be despised ... In addition, the table must end with an empty record {null,null,0,null}.
The initialization function of the module is called by the Python interpreter when the module is loaded, and if your module is named Foo, it is called Initfoo. The PY_INITMODULE3 function is typically used to define a module.
3, now let's compile the foo.c file into an extension module, which is compiled with the following command:
Gcc-shared-i/usr/include/python2.6 Foo.c-o foo.so
Note the name of the shared object must be the same as the string passed to the Py_initmodule3 function, and the other option is to add a module suffix, so the above Foo module can be named Foo.so or foomodule.so.
4, the above compilation method can complete the task, but the better way to build the extension module is to use Distutils. First write a setup.py script:
From Distutils.core import Setup, Extension
Setup (name = ' Foo ', Version = ' 1.0 ', ext_modules = [Extension (' foo ', [' foo.c '])])
Then execute the following command to build:
Python./setup.py Build
This generates a build subdirectory in the current directory that contains the intermediate generated foo.o and the last generated foo.so. The simplest approach, of course, is to build and install the module using the following command:
Python./setup.py Install
Note: Due to the need to obtain Dist-packages write permissions, it is best to switch to the root user, if you directly use the SU switch, the following error occurs:
Su:authentication failure
Then set a new password for the root user:
sudo passwd root
Then switch to the root user with the new password. When we look at the details of build, we can find the following sentence:
Copying build/lib.linux-i686-2.6/foo.so-/usr/local/lib/python2.6/dist-packages
This is the copy of the generated module to/usr/local/lib/python2.6/dist-packages, so that our Foo module installed in the system, we can verify the following, in the Python command line,
Import Foo
Dir (foo)
The results are as follows:
[' __doc__ ', ' __file__ ', ' __name__ ', ' __package__ ', ' Bar ']
Oh, good, this Foo module is now the same as other system modules, because Dist-packages is in the path of Sys.path,
5, now we have a build and install the C extension module, the rest is to introduce the new module in Python code, and call its method
Import Foo
Foo.bar ()
Of course, since we haven't done anything yet in the bar function in the C module, we have nothing now, in the next article we implement: 1) pass parameters from the Python script to the C module. 2) return values from the C module to the external Python script
The night has been deep, this Python and C/c++,java series of the first article is temporarily written here ...
Extending Python with C language