C语言扩展Python(一)
原文地址 http://my.oschina.net/max1984/blog/89122?from=20121118
Python具有很好的开发灵活性,最大的特点是C语言可以对Python进行扩展,目前工作中正在进行相关的开发,第一篇文章作为基础.
实现C函数,用Python API封装,实现俩个功能,1.say_hello,打印hello world! 2.calc_pv,做加法用算.
以下为使用方法:
01 |
Python 2.7 . 3 (default,
Nov 13 2012 , 11 : 17 : 50 ) |
02 |
[GCC 4.1 . 2 20080704 (Red
Hat 4.1 . 2 - 48 )]
on linux2 |
03 |
Type "help" , "copyright" , "credits" or "license" for more
information. |
04 |
>>> |
05 |
>>> import session |
06 |
>>> |
07 |
>>>
session.sayhello() |
08 |
hello
world! |
09 |
>>>
session. sum ( 1 , 2 ) |
10 |
3 |
11 |
>>> |
01 |
/** |
02 |
* |
03 |
*
$ cpython_eg1.c version1.0 2012-11-13 xxx $ |
04 |
*
@2012 xxx.com.cn |
05 |
* |
06 |
*/ |
07 |
08 |
#include
"Python.h" |
09 |
10 |
static PyObject
*say_hello(PyObject *self) |
11 |
{ |
12 |
printf ( "%s\n" , "hello
world!" ); |
13 |
/**
python 没有void 类型,在没有返回值的时候,必须使用Py_RETURN_NONE*/ |
14 |
Py_RETURN_NONE; |
15 |
} |
16 |
17 |
static PyObject
*calc_pv(PyObject *self,PyObject *args) |
18 |
{ |
19 |
20 |
int i_ct=0; |
21 |
int j_ct=0; |
22 |
/**
PyArg_ParseTuple 用来解析参数,PyArg_ParseTuple \ |
23 |
(PyObject
*args, const char *format, ...)*/ |
24 |
/**
i代表int,同理s代表char *,d代表double,多个参数可以直接使用'is'这样使用,'|'代表或的意思, |
25 |
代码中'|'最后一个i是可选参数*/ |
26 |
if (!
PyArg_ParseTuple(args, "i|i" ,
&i_ct,&j_ct)) |
27 |
return NULL; |
28 |
return Py_BuildValue( "i" ,
(i_ct+j_ct)); |
29 |
} |
30 |
31 |
/* |
32 |
*
Function table |
33 |
*
PyMethodDef结构体定义: |
34 |
*
struct PyMethodDef { |
35 |
*
const char *ml_name; // The name of the built-in function/method |
36 |
*
PyCFunction ml_meth; // The C function that implements it |
37 |
*
int ml_flags; // Combination of METH_xxx flags, which mostly |
38 |
*
describe the args expected by the C func |
39 |
*
const char *ml_doc; // The __doc__ attribute, or NULL |
40 |
*
}; |
41 |
* |
42 |
*/ |
43 |
44 |
static PyMethodDef
addMethods[] = |
45 |
{ |
46 |
//
METH_NOARGS 无参数 |
47 |
{ "sayhello" ,(PyCFunction)say_hello,METH_NOARGS, "say
hello!" }, |
48 |
//
METH_VARARGS 带有参数 |
49 |
{ "sum" ,(PyCFunction)calc_pv,METH_VARARGS, "calc
pv" }, |
50 |
/**NULL代表结束位,Py_InitModule会以NULL代表函数列表结束*/ |
51 |
{NULL,
NULL, 0, NULL} |
52 |
}; |
53 |
54 |
/* |
55 |
*
Initialize |
56 |
* |
57 |
*
如果定义模块名字为session,必须要有initsession(void)函数作为动态接口 |
58 |
*
Python会自动寻找接口调用 |
59 |
*/ |
60 |
61 |
PyMODINIT_FUNC
initsession( void ) |
62 |
{ |
63 |
PyObject
*module; |
64 |
/**
Initialize module ,addMethods是需要初始化的函数列表*/ |
65 |
module
= Py_InitModule( "session" ,
addMethods); |
66 |
if (!module) |
67 |
return ; |
68 |
} |
最后是编译的过程,首先创建setup.py,内容如下
1 |
from distutils.core import setup,
Extension |
2 |
3 |
module1 = Extension( 'session' ,sources = [ 'cpython_eg1.c' ],language = 'c' ) |
4 |
5 |
setup
(name = 'emar_py_lib' ,
version = '1.0' ,
\ |
6 |
description = 'This
is a demo package' ,
\ |
7 |
ext_modules = [module1]) |
1.python setup.py build
2.sudo python setup.py install