1、python扩展模块的组成
  在python中,对于一些和系统相关的模块或者对性能要求很高的模块,通常会把这个模块C化。扩展模块中主要包含下面几个部分:
  · init函数,函数名为:init+模块名,这个函数负责初始化模块,包括设置模块中的方法、对象和其它相关数据的初始化。这个函数是必须的,在脚本中第一次导入这个模块的时候,会先执行这个方法。
  · 定义模块方法描述表,它是一个static类型的PyMethodDef数据结构,用来描述模块中定义的方法。
  · C函数定义,这些函数是方法描述表中方法的具体实现。
  · 如果模块中定义了类,那么还要定义类方法描述表和对象类型。
  2、实现python扩展模块实例
  当然,有了上面的组成部分,你还是不知道怎么实现一个模块,下面用官方的一个例子来演示怎么实现一个python扩展模块,这个扩展模块用来实现在python中执行命令行命令。
// spam.c
1 #include "Python.h"
2
3 static PyObject *SpamError;
4
5 static PyObject *
6     spam_system(PyObject *self, PyObject *args)
7 {
8     const char *command;
9     int sts;
10
11     if (!PyArg_ParseTuple(args, "s", &command))
12         return NULL;
13     sts = system(command);
14     if (sts < 0) {
15         PyErr_SetString(SpamError, "System command failed");
16         return NULL;
17     }
18     return PyLong_FromLong(sts);
19 }
20
21 static PyMethodDef SpamMethods[] = {
22     {"system",  spam_system, METH_VARARGS,
23     "Execute a shell command."},
24     {NULL, NULL, 0, NULL}        /* Sentinel */
25 };
26
27 PyMODINIT_FUNC
28     initspam(void)
29 {
30     PyObject *m;
31
32     m = Py_InitModule("spam", SpamMethods);
33     if (m == NULL)
34         return;
35
36     SpamError = PyErr_NewException("spam.error", NULL, NULL);
37     Py_INCREF(SpamError);
38     PyModule_AddObject(m, "error", SpamError);
39 }
  上面的initspam是模块的初始化函数,函数开始调用了Py_InitModule初始化了一个名为spam的模块,模块的方法描述表是SpamMethods,它描述了模块有个名为system的方法,这个方法的c/c++实现是spam_system函数。从spam_system函数可以看到它是调用system函数执行从python传过来的命令。有了上面的代码,我们怎样在python中使用了?很简单,先将上面代码编译成动态链接库,然后直接在python中用import语句导入这个模块可以用了。在Windows下的用vs编译行,不过在vs建立了dll工程后,需要设置下工程的属性,目的是设置python扩展涉及到的头文件路径和动态库。具体设置如下:先在VC++目录中设置include和lib路径,然后在链接器的附加依赖项中添加python27.lib库。

  设置好后直接编译可以了,将编译生成的dll文件后缀名改成pyd,然后可以在python中直接用import导入这个模块了。是不是非常的简单!!!!

  3、实现python扩展模块中定义类
  上面的实现是在模块中定义函数来实现执行命令行命令,我们也可以在模块中定义类,然后用类的方法来执行这个命令。代码如下:
// spam.c
1 #include "Python.h"
2
3 static PyObject *SpamError;
4
5 static PyObject *
6     spam_system(PyObject *self, PyObject *args)
7 {
8     const char *command;
9     int sts;
10
11     if (!PyArg_ParseTuple(args, "s", &command))
12         return NULL;
13     sts = system(command);
14     if (sts < 0) {
15         PyErr_SetString(SpamError, "System command failed");
16         return NULL;
17     }
18     return PyLong_FromLong(sts);
19 }
20
21 static PyMethodDef SpamMethods[] = {
22     {"system",  spam_system, METH_VARARGS,
23     "Execute a shell command."},
24     {NULL, NULL, 0, NULL}        /* Sentinel */
25 };
26
27 PyTypeObject *SpamType = NULL;
28
29 PyMODINIT_FUNC
30     initspam(void)
31 {
32     static PyTypeObject _SpamType = {
33         PyObject_HEAD_INIT(NULL)
34         0,                                // ob_size
35         "spam.Spam",                // tp_name
36         sizeof(PyObject),                // tp_basicsize
37         0,                                // tp_itemsize
38         0,        // tp_dealloc
39         0,                                // tp_print
40         0,                                // tp_getattr
41         0,                                // tp_setattr
42         0,                                // tp_compare
43         0,            // tp_repr
44         0,                                // tp_as_number
45         0,                                // tp_as_sequence
46         0,                                // tp_as_mapping
47         0,                                // tp_hash
48         0,                                // tp_call
49         0,            // tp_str
50         0,                                // tp_getattro
51         0,                                // tp_setattro
52         0,                                // tp_as_buffer
53         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,    // tp_flags
54         0,                    // tp_doc
55         0,                                // tp_traverse
56         0,                                // tp_clear
57         0,                                // tp_richcompare
58         0,                                // tp_weaklistoffset
59         0,                                // tp_iter
60         0,                                // tp_iternext
61         SpamMethods,                    // tp_methods
62         0,                                // tp_members
63         0,                // tp_getset
64         0,                                // tp_base
65         0,                                // tp_dict
66         0,                                // tp_descr_get
67         0,                                // tp_descr_set
68         0,                                // tp_dictoffset
69         0,            // tp_init
70         0,                                // tp_alloc
71         PyType_GenericNew,                // tp_new
72     };
73
74     PyObject *m;
75
76     m = Py_InitModule("spam", NULL);
77     if (m == NULL)
78         return;
79     if (PyType_Ready(&_SpamType) < 0)
80         return;
81     SpamType = &_SpamType;
82     Py_INCREF(SpamType);
83     PyModule_AddObject(m, "Spam", (PyObject*)SpamType);
84     SpamError = PyErr_NewException("spam.error", NULL, NULL);
85     Py_INCREF(SpamError);
86     PyModule_AddObject(m, "error", SpamError);
87 }