- 首先,编写包含py接口的c源文件,称为wrap.c。这一步可以使用swig带过。 例如:swig
-python foo.i
- 接着,对wrap.c进行编译,生成XX.so。这一步可以使用 distutils带过。如果要用 distutils的话,则需要首先编写一个py脚本。示例:setup(name
= ‘example‘, version = ‘1.0‘, ext_modules = [Extension(‘example‘, [‘wrap.c‘,‘example.c‘])]) 注意:句子中的list不仅不要包含wrap源文件,还要包含函数的原始源文件
- 上一步的so文件便是最终可以使用的库文件,把该文件放入py的lib中或者当前目录,即可导入c语言扩展模块进行使用。如果之前用过swig,还要把相应的so文件移入模块文件夹中并在文件名前加上_。示例:
cp printf.so /usr/lib64/python2.7/site-packages/_printf.so
经过了之前的学习,我已经能够顺利的使用写好的wrap文件生成c扩展库了。今天我决定把自己的那些函数也都编译成扩展库。虽然我可以直接轻松的使用swig实现,但是swig要求必须把写好的库文件放入指定目录,否则就出问题,然而我想的是把所有需要的库都放入一个本地目录来方便程序的移植,swig显然跟我的想法相悖。因此我决定自己编写wrap文件。
wrap文件中有几个关键函数必须掌握。首先是:PyObject* wrap_fact(PyObject* self, PyObject* args)。这个函数的作用是分析python传进来的参数并执行响应的c函数。PyArg_ParseTuple(args, "is", &n,&c)函数可以用来分析python传进来的(元组)参数。其中的字符串参数是一个格式化字符串,里面is分别表示整形和字符串。后边需要加上存储参数的c变量地址,这里需要注意的是,这些参数必须是用来存储参数的变量的地址,即使要存储的是一个字符串也一样,这点·跟scanf还是有一定差异的。分析完参数之后,就可以直接利用得到的这些参数调用相应的c函数。之后可以利用return
Py_BuildValue("i", result)向python返回值。示意中语句可以将result变量的值以整形返回。总的来说,这个函数的实际作用就是取得python调用相应函数时所传递的参数,然后利用这些参数执行这个函数中的c代码段,然后将c代码段中的指定值返回给python。
然是是一个指针数组:static PyMethodDef exampleMethods[]。这个数组用来存储c函数映射表。每个c函数都需要有一个这样的{"fact", wrap_fact, METH_VARARGS, "Caculate N!"}数组,其中的元素依次代表python中函数的名字,接口函数地址,参数类型,函数描述。需要扩展多少个函数就要有多少个这样的数组。
最后是模块初始化函数:void initexample()。注意这个函数的名字是有讲究的,必须是init模块名字。里边需要包含语句:m = Py_InitModule("example", exampleMethods);其中的参数分别代表模块名字、函数映射表数组。
示例:
#include <Python.h>
extern int sendsyslog(const char *addr,int port,int type);
extern int sendtoac2(int type);
extern int sendtoac1(int type);
extern int rarecv(int wtime,const char *if_name2);
PyObject* sendcmsg_syslog(PyObject* self, PyObject* args)
{
int port,type, result;
char *addr;
if (! PyArg_ParseTuple(args, "sii", &addr,&port,&type))
return NULL;
result = sendsyslog(addr,port,type);
return Py_BuildValue("i", result);
}
PyObject* sendcmsg_sendac1(PyObject* self, PyObject* args)
{
int type, result;
if (! PyArg_ParseTuple(args, "i", &type))
return NULL;
result = sendtoac1(type);
return Py_BuildValue("i", result);
}
static PyMethodDef sendcmsgMethods[] =
{
{"syslog", sendcmsg_syslog, METH_VARARGS, "send syslog msg!"},
{"sendac1", sendcmsg_sendac1, METH_VARARGS ,"send a q msg to client1"},
{"sendac2", sendcmsg_sendac2, METH_VARARGS ,"send a q msg to client2"},
{"rarecv", sendcmsg_rarecv, METH_VARARGS ,"detect ra msg"},
{NULL, NULL}
};
void initsendcmsg()
{
PyObject* m;
m = Py_InitModule("sendcmsg", sendcmsgMethods);
}