一个典型的Python扩展模块至少应该包含三个部分:导出函数、方法列表和初始化函数
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
1、模块编写
==============================================mym.c======================begin
/*filename mym.c*/
#include "Python.h"
double func(double x,double y)
{
return x+y;
}
/*------------------导出函数-----------------------------*/
/*
* PyObject* method(PyObject* self, PyObject* args);
* 该函数是Python解释器和C函数进行交互的接口,
* 带有两个参数:self和args。
* 参数self只在C函数被实现为内联方法(built-in method)时才被用到,通常该参数的值为空(NULL)。
* 参数args中包含了Python解释器要传递给C函数的所有参数,
* 通常使用Python的C语言扩展接口提供的函数PyArg_ParseTuple()来获得这些参数值。
*/
/*对函数进行包装,每一个Python对象在C中都是PyObject* 类型*/
static PyObject *mym_func(PyObject *self,PyObject *args)
{
double arg1, arg2, result;
if (!PyArg_ParseTuple(args,"dd",&arg1,&arg2))
{
return NULL;
}
result = func(arg1,arg2);
return Py_BuildValue("d",result);
}
/*------------------------方法列表---------------------------*/
/*
* 方法列表中给出了所有可以被Python解释器使用的方法
* 方法列表中的每项由四个部分组成:
* 方法名、导出函数、参数传递方式和方法描述。
* 方法名是从Python解释器中调用该方法时所使用的名字。
* 参数传递方式则规定了Python向C函数传递参数的具体形式,
* 可选的两种方式是METH_VARARGS和METH_KEYWORDS,
* 其中METH_VARARGS是参数传递的标准形式,它通过Python的元组在Python解释器和C函数之间传递参数,
* 若采用METH_KEYWORD方式,则Python解释器和C函数之间将通过Python的字典类型在两者之间进行参数传递
*/
/* 建立一个模块函数的列表*/
static struct PyMethodDef mymMethods[] =
{
{"func",mym_func,METH_VARARGS},
{NULL,NULL,0,NULL}
};
/*----------------------初始化函数------------------*/
/*
* 所有的Python扩展模块都必须要有一个初始化函数,以便Python解释器能够对模块进行正确的初始化。
* Python解释器规定所有的初始化函数的函数名都必须以init开头,并加上模块的名字。
*/
/* 对模块进行初始化*/
void initmym()
{
Py_InitModule("mym",mymMethods);
}
============================================================mym.c=================end
2、编译
要在Python解释器中使用C语言编写的扩展模块,必须将其编译成动态链接库的形式
用distutils模块对包进行编译,下面建立编译的脚本
============================================================setup.py================begin
#filename setup.py
from distutils.core import setup, Extension
import os
import sys
extra_compile_args = ['-q64']
extra_link_args = ['-berok','-q64']
my_inc = os.path.join(os.getcwd(), '.')
include_dirs = [my_inc, '/usr/include']
library_dirs = ['/usr/lib']
libraries = [ ]
libraries_ws = []
module1 = Extension(name = 'mym',
sources = ['mym.c'],
extra_compile_args = extra_compile_args,
extra_link_args = extra_link_args,
include_dirs = include_dirs,
library_dirs = library_dirs,
libraries = libraries,
)
setup (name = 'mym', version = '1.0', description = 'This is a demo package', ext_modules = [module1])
============================================================setup.py================end
脚本在aix 64位机器xlc_r编译器成功编译,其他机器或编译器需要修改
Python_64 setup.py build 编译成功
3、使用
引入Python解释器
由于没有安装,可能找不到mym.so文件,直接进入到build文件夹下的mym.so所在的目录中,启动python
Python_64
>>> import mym
>>> mym.func(5,3)
8.0
>>>
参考文档:
http://blog.tianya.cn/blogger/post_read.asp?BlogID=3616841&PostID=36654684>