• python封装C库实现对C代码调用


    Python封装C库实现对C库调用

     

     本文由希希大队长创作,请勿盗链

    在实际开发过程中,由于有些经典高效的库是由C写的,尤其涉及到计算密集型的,python很难做到高效,因此我们需要实现将C库作为模块引入python,供我们使用,在这个过程里面,希望大家少踩坑

    我们来以一个小demo为例,这里首先展示下demo目录结构

     

    demo
      -- install.sh # sh构建文件
      -- main.py    # 测试文件
      -- setup.py # 构建py扩展库文件
      -- test.c   # C扩展库

    install.sh

    python3 setup.py install

    rm -rf ./dist
    rm -rf ./build

    setup.py

    from distutils.core import setup, Extension

    setup(name='aaa', # 定义的模块名
         version='1.0',
         ext_modules=[
             Extension('aaa', ['test.c']) # aaa为c文件中定义的模块名,test.c为 c文件路径
        ]
        )

    test.c 简单的fib函数封装,以下内容为python3的封装方式,python2可自行百度

    #include <Python.h>

    //a func to calc fib numbers
    int cFib(int n)
    {
       if (n<2) return n;
       return cFib(n-1) + cFib(n-2);
    }

    // 实现c与py参数返回值桥接
    static PyObject* fib(PyObject* self,PyObject* args)
    {
       int n;
       if (!PyArg_ParseTuple(args,"i",&n))
           return NULL;
       return Py_BuildValue("i",cFib(n));
    }

    // 定义模块包含的功能/函数
    static PyMethodDef module_methods[] = {
      {"fib",(PyCFunction) fib, METH_VARARGS,"calculates the fibonachi number"},
      {NULL,NULL,0,NULL}
    };

    // 封装一个模块结构体
    static struct PyModuleDef aaa =
    {
       PyModuleDef_HEAD_INIT,
       "aaa", /* name of module */
       "",          /* module documentation, may be NULL */
       -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
       module_methods
    };

    // init该模块为py模块
    PyMODINIT_FUNC PyInit_aaa(void)
    {
       return PyModule_Create(&aaa);
    }

    main.py 测试c扩展库是否构建成功

    import aaa

    if __name__ == '__main__':

       for num in range(10):
           print(aaa.fib(num))
            

    需要注意的是,你期待生成的模块名需与c文件中几个关键的名称须保持一致

    也就是以上例子中setup.py和test.c中所有为aaa的地方

    以上文件准备好后,开始打包

    首先进入demo目录

    cd demo
     执行构建sh文件
    install.sh

    不报错即构建成功

    测试:

    在demo目录下执行

    python3 main.py

    正常输出:

    0
    1
    1
    2
    3
    5
    8
    13
    21
    34

    如果执行测试脚本时提示导入模块问题,例:

    ImportError:The dynamic module does not define the init function

    请检查 期待生成的模块名需与c文件中几个关键的名称须保持一致,即以上例子中setup.py和test.c中所有为aaa的地方

     

    本文完结!

     
    程序猿,要对自己狠一点!
  • 相关阅读:
    MyBatis学习(三)
    MyBatis学习(二)
    Linux(Ubuntu)下MySQL的安装与配置
    IO 流读取文件时候出现乱码 文件编码格式问题 怎么转换解决方法
    spring boot下MultipartHttpServletRequest如何提高上传文件大小的默认值
    Mybatis 批量插入时得到插入的id(mysql)
    对PDF的操作
    利用nginx进行集群部署
    Spring boot学习笔记之@SpringBootApplication注解
    git的使用命令
  • 原文地址:https://www.cnblogs.com/dongxixi/p/14498785.html
Copyright © 2020-2023  润新知