• 【python笔记】扩展模块


    一个典型的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>

    http://www.ibm.com/developerworks/cn/linux/l-pythc/>

  • 相关阅读:
    springcloud有哪些特征
    可变参数
    递归
    增强的for循环
    Scanner对象
    注释
    Markdown常见的样式语法
    副本机制
    消费者分区分配策略
    SpringMVC 登陆判断
  • 原文地址:https://www.cnblogs.com/ningth/p/2351245.html
Copyright © 2020-2023  润新知