初始化c实现的python模块
  为了能在python脚本中调用到c中定义的方法,需要先在c中定义一个python模块,然后在脚本中import这个模块,后通过这个模块来间接调用c中定义的方法。例如,我们通过c定义了一块内存区域data和对这个内存区域操作的函数SetData与GetData(代码如下),怎样在脚本中调用SetData与GetData函数来操作data呢?其实关键问题是怎么样在脚本中调用SetData和GetData函数,如果能在脚本中调用这两个函数,自然能操作data了。python中通过模块的方式来解决这个问题。
1 #define min(a,b)    (((a) < (b)) ? (a) : (b))
2
3 char data[1024];
4
5 void SetData(const char *str)
6 {
7     strncpy(data, str, min(strlen(str) + 1, 1024));
8 }
9
10 const char *GetData()
11 {
12     return data;
13 }
  在c中定义一个python模块有特定的步骤,具体代码如下:
1 PyDoc_STRVAR(PySetData_doc__, "
2 测试
3
4 PySetData(str)
5 str: 出入的字符串
6 返回:
7 null
8 ");
9 static PyObject* PySetData(PyObject *self, PyObject *args)
10 {
11     const char* str = NULL;
12     if ( !PyArg_ParseTuple(args, "s", &str) )
13     {
14         return 0;
15     }
16     SetData(str);
17     Py_RETURN_NONE;
18 }
19
20 PyDoc_STRVAR(PyGetData_doc__, "
21 打印数据
22
23 PyGetData()
24 返回:
25 data
26 ");
27 static PyObject* PyGetData(PyObject *self, PyObject *args)
28 {
29     const char* str = NULL;
30     return PyString_FromString(GetData());
31 }
32
33 static PyMethodDef module_methods[] = {
34     {"py_set_data", PySetData, METH_VARARGS, PySetData_doc__},
35     {"py_get_data", PyGetData, METH_VARARGS, PyGetData_doc__},
36     {NULL}
37     };
38 void InitCCallPy()
39 {
40     PyObject *module = Py_InitModule3("pycallc", module_methods,
41         "python call c");
42 }
  Py_InitModule3用来定义一个python模块,第一个参数是模块的名字,第二个参数是模块中的方法描述集合,第三个参数是模块的描述信息。上面代码中我们定义了一个叫pycallc的模块,方法描述集合module_methods描述了两个方法py_set_data和py_get_data,这两个方法对应的函数地址是PySetData和PyGetData,这两个函数终会分别调用前面定义的SetData和GetData。这样我们在python脚本中通过pycallc模块的py_set_data和py_get_data方法可以设置和获取data数据了。看了上面的实现,其实这个python模块的主要作用是把c中定义的函数再封装一次,封装的函数能够被python识别。
  在python脚本中调用c实现的python模块
  由于前面已经通过c代码初始化了一个python模块pycallc,那么在脚本中我们可以通过import导入这个模块,并调用这个模块中的函数。具体代码如下:
1 # -*- coding: utf-8 -*-
2
3 import pycallc
4
5 def test():
6     print 'in python : ', pycallc.py_get_data()
7     pycallc.py_set_data("change hello world!")
  这样我们实现了在python脚本中调用c中的方法。
  上面完整的代码demo的链接:https://github.com/morningstatus/python/tree/master/ccallpy
  总结
  从上面c调用python,python调用c,其实都是一些固定的步骤,知道会用了,没有会不会的问题,只有想不想知道的问题。没有接触这个技术前可能觉得它很高深,但其实只要稍微花点心思去了解它,它也其实没有这么难。计算机很多技术不外乎都是这样,只有你想不想的问题,没有你会不会的问题,多问,多思考,多学习,总有你也能成为技术大牛。