原来是搞c的,python有c的扩展接口,所以先学习,写下来加深印象,google一下,网上很多例子,也有几种扩展方法:常规python C API,SWIG,boost,pyrex等等。SWIG和boost是c++的实现,c++不是很熟,所以直接看的C API。
如果只是要将现成的C文件扩展成python中的模块,那么C的API看着不是很难。
首先在想要扩展的C文件后#include <python.h>
然后需要三个API接口
导出函数,用来与c文件中的函数交互。参数self在c函数被用于内联函数的时候才用到,而args包括了所有c函数中的参数,
通过PyArg_ParseTuple()获取args
PyObject* method(PyObject* self, PyObject* args);
方法列表,包含了所有在python中可以使用的方法
static PyMethodDef exampleMethods[] =
{
{"method_name", method, METH_VARARGS, "Description..."},
{NULL, NULL}
};
初始化函数,必须以init开头,如果欲使用的模块名为example,那么初始函数名为initexample
void initexample()
{
PyObject* m;
m = Py_InitModule("example", exampleMethods);
}
在build前需要一个setup脚本,用到了distutils模块
from distutils.core import setup, Extension
setup(name="example", version="1.0",
ext_modules=[Extension("example", ["example.c"])])
最后就是编译
$python setup.py build
我的文件如下
[code]
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
int iteract_sum(int n)
{
if(n <= 1)
return n;
else
return n + iteract_sum(n - 1);
}
#include <Python.h>
static PyObject* Ext_sum(PyObject* self, PyObject* args)
{
int n, result;
if(! PyArg_ParseTuple(args, "i:iteract_sum", &n))
return NULL;
result = iteract_sum(n);
return Py_BuildValue("i", result);
}
static PyMethodDef Methods[]=
{
{"Ext_sum", Ext_sum, METH_VARARGS, "Caculate sum from 1 to n!"},
{NULL, NULL}
};
PyMODINIT_FUNC initext(void)
{
Py_InitModule3("ext", Methods, "do sth.");
}
[/code]
我在cygwin里编译的结果
$ python ext-setup.py build
running build
running build_ext
building 'ext' extension
gcc -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/include/python2.5 -c ext.c -o build/temp.cygwin-1.5.25-i686-2.5/ext.o
creating build/lib.cygwin-1.5.25-i686-2.5
gcc -shared -Wl,--enable-auto-image-base build/temp.cygwin-1.5.25-i686-2.5/ext.o -L/usr/lib/python2.5/config -lpython2.5 -o build/lib.cygwin-1.5.25-i686-2.5/ext.dll
最后是生成dll的动态链接库
直接在python中就可以import ext了,凑合着用用也行了,呵呵