小结两种在Python中导入C语言扩展库的方法

分类: Pythoner2009-08-18 20:44 2563人阅读 评论(1) 收藏 举报
python扩展c语言importstring

一种是Python文档的推荐方案,采用C API扩展写法:

在D:建一个add.c文件,输入

[cpp] view plaincopy
  1. //add.c
  2. //
  3. #include <Python.h>;
  4. static PyObject* add(PyObject *self, PyObject *args);
  5. //一定声明为static,把他们限制在这个文件范围里。 几乎所有的参数都是PyObject类型。 在python,每个东西都是object。
  6. static PyObject* add(PyObject* self, PyObject* args)
  7. {
  8. int x=0 ;
  9. int y=0;
  10. int z=0;
  11. if (! PyArg_ParseTuple(args, "i|i", &x, &y))
  12. return NULL;
  13. /*第一个参数是self,这个是python用的, 每个函数都要有。我们暂时不管。args是一个参数列表。她把所有的参数都整合成一个string。所以
  14. 我们需要从这个string里来解析我们的参数。PyArg_ParseTuple来完成这个任务。第一个参数是args, 就是我们要转换的参数。第二个是格式符号。
  15. “s”代表是个string。 从args里提取一个参数就写"s", 两个的话就写"s|s", 如果是一个string,一个int,就写"s|i", 和printf差不多。第三个
  16. 参数就是提取出来的参数放置的真正位置。必须传递这个参数的地址。对于add, 他将提取两个参数。分别是x和y。*/
  17. z=x+y;
  18. return Py_BuildValue("i", z);
  19. /*调用完之后我们需要返回结果。这个结果是c的type或者是我们自己定义的类型。必须把他转换成PyObject, 让python认识。这个用Py_BuildValue
  20. 来完成。他是PyArg_ParseTuple的逆过程。他的第一个参数和PyArg_ParseTuple的第二个参数一样, 是个格式化符号。第三个参数
  21. 是我们需要转换的参数。Py_BuildValue会把所有的返回只组装成一个tutple给python。*/
  22. }
  23. static PyMethodDef addMethods[] =
  24. {
  25. {"add",  add, METH_VARARGS, "Execute a shell command."},
  26. {NULL, NULL, 0, NULL}
  27. };
  28. /*这个是一个c的结构。他来完成一个映射。 我们需要把我们扩展的函数都映射到这个表里。表的第一个字段是python真正认识的。是python
  29. 里的方法名字。 第二个字段是python里的这个方法名字的具体实现的函数名。 在python里调用add, 真正执行的是用c写的add函数。
  30. 第三个字段是METH_VARARGS, 他告诉python,add是调用c函数来实现的。第四个字段是这个函数的说明。如果你在python里来help这个函数,
  31. 将显示这个说明。相当于在python里的函数的文档说明。*/
  32. PyMODINIT_FUNC initadd()
  33. {
  34. Py_InitModule("add", addMethods);
  35. }
  36. /*注意,这个函数的名字不能改动。 必须是init+模块名字。 我们的模块名字是add。所以这个函数是initadd()。
  37. 这样python在导入add 的模块时候,才会找到这个函数,并调用。这个函数调用Py_InitModule来将模块名字和映射表结合在一起。
  38. 他表示,add这个模块使用addMethods这个映射表。python应该这样导入我们的module的.*/

然后在D:盘建立setup.py

[python] view plaincopy
  1. from distutils.core import setup, Extension
  2. module1 = Extension('add', sources = ['add.c'])
  3. setup (name = 'PackageName', version = '1.0', description = 'This is a ADD package', ext_modules = [module1])

将cmd切换到D:

输入setup.py build --compiler=mingw32 -verbose

这里我选择了mingw32,否则在我的机器上它会用msvc,而这会有一些小错误

运行成功后会在(当前目录的)D:/build/lib.win32-2.6下生成add.pyd

下面就在Python中导入

>>> import sys
>>> sys.path.append("D:/build/lib.win32-2.6")

>>> import add
>>> add.add(3,2)
5

Bingo!

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

以上是用C API的扩展方式,它的写法比较麻烦。以下用ctypes直接导入dll模块。

如果是在Windows下面:

首先在D:建立文件spam.c

[cpp] view plaincopy
  1. //spam.c
  2. //
  3. #include <windows.h>
  4. BOOL APIENTRY
  5. DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  6. {
  7. return TRUE;
  8. }
  9. __declspec(dllexport) int
  10. multiply(int num1, int num2)
  11. {
  12. return num1 * num2;
  13. }
  14. //这是一个标准的Windows DLL的写法。

我用cl来编译它,现在我渐渐喜欢上了用cl来编译,省得建一个好几兆的项目,而且参数可以灵活选择。后面我会继续学习如何写make file。

在cmd输入cl -I"d:/programs/python26/include" spam.cpp,会生成spam.obj

再输入link spam.obj /DLL /libpath:"d:/programs/python26/libs",生成spam.dll

下面到python中导入:

>>> import ctypes
>>> cdll=ctypes.cdll.LoadLibrary('d:/spam.dll')

>>> cdll.multiply(2,3)
6

如果是在Linux下面:

在/home/Henry下建立spam.c

[cpp] view plaincopy
  1. char *foo(){
  2. char *p = "hello world";
  3. return p;
  4. }
  5. void foo1(char *p){
  6. strcpy(p, "hello world");
  7. }

编译:$ gcc -o libspam.so -fpic -shared spam.c

进入Python:

[python] view plaincopy
  1. #返回指针:
  2. >>> import ctypes
  3. >>> hello = ctypes.cdll.LoadLibrary("/home/Henry/libspam.so")
  4. >>> p = hello.foo()
  5. >>> ctypes.c_char_p(p).value
  6. >>> 'hello world'
  7. #传入buffer:
  8. >>> b = ctypes.create_string_buffer(12)
  9. >>> hello.foo1(b)
  10. >>> b.value
  11. >>> 'hello world'

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

但是ctypes对C++的DLL导入不行。对于C++库的导入还是要借助于Boost.python。

我一定会回来的!

  • 上一篇练练手,练练手——C语言用递归对链表逆序
  • 下一篇导出与导入C++ DLL小记

小结两种在Python中导入C语言扩展库的方法相关推荐

  1. 两种在QGIS中制作高德铁路线型符号的方法

    1. 概述 恰当的地图符号除了可以直观地表达地图上的要素之外,还可以让地图看起来更加美观和更具有耐看性. 高德地图作为常用的地图之一,其许多的配色和样式方案值得我们在制图的时候参考,所以这里以铁路线型 ...

  2. 两种在CAD中加载在线卫星影像的方法

    概述 经常使用CAD的朋友应该会有这样的一个烦恼,就是当加载卫星图到CAD中进行绘图的时候,由于CAD本身的限制和电脑性能等原因,往往不能加载太大的地图图片到CAD内,这里给大家介绍两种在CAD内加载 ...

  3. python中读写excel的扩展库_Python读写Excel文件第三方库汇总,你想要的都在这儿!...

    常见库简介 xlrd xlrd是一个从Excel文件读取数据和格式化信息的库,支持.xls以及.xlsx文件. http://xlrd.readthedocs.io/en/latest/ 1.xlrd ...

  4. python中导入的模块不能直接当方法用,需要采用模块.方法名或模块 as 别名,再别名.方法的形式

    eg 方法一:from data import splitXdataset as sp sp.split_dataset() 或者 from data import splitXdataset spl ...

  5. python用于导入模块或模块中的对象_在 Python 中导入模块中的对象有哪几种方式? (5.0分)_学小易找答案...

    [判断题]尽管可以使用 import 语句一次导入任意多个标准库或扩展库,但是仍建议每次只导入一个标准库或扩展库. (2.0分) [填空题]表达式 int(str(34)) == 34 的值为 ___ ...

  6. python csv库,Python 中导入csv数据的三种方法

    Python 中导入csv数据的三种方法,具体内容如下所示: 1.通过标准的Python库导入CSV文件: Python提供了一个标准的类库CSV文件.这个类库中的reader()函数用来导入CSV文 ...

  7. python导入类有红线_解决Python中导入自己写的类,被划红线,但不影响执行的问题...

    1. 错误描述 之前在学习Python的过程中,导入自己写的包文件时,与之相关的方法等都会被划红线,但并不影响代码执行,如图: 看着红线确实有点强迫症,并且在这个过程当时,当使用该文件里的方法时不会自 ...

  8. python使用spark_apache spark - 在python中导入pyspark

    apache spark - 在python中导入pyspark 这是另一个从未回答过的论坛上的别人问题的副本,所以我想我会在这里重新提问,因为我有同样的问题. (见[http://geekple.c ...

  9. python调用shell命令-python中执行shell命令的几个方法小结

    最近有个需求就是页面上执行shell命令,第一想到的就是os.system, 复制代码 代码如下: os.system('cat /proc/cpuinfo') 但是发现页面上打印的命令执行结果 0或 ...

最新文章

  1. 阿里安全新研究:给图片打“马赛克”就能骗过 AI 视觉系统
  2. latex 常用小结
  3. Kubernetes(K8s)容器设计模式实践案例 – 分散收集模式
  4. 自动驾驶系统为何要打上「思想钢印」?北京顺义闹市区里藏着毫末智行的谜底...
  5. 忽如一夜冬风来,团队忽然就解散了
  6. linux c之动态打开链接库(dlopen dlsym dlclose)
  7. html数字自动滚动代码怎么写,你可能需要这样的大屏数字滚动效果
  8. centos7.3二进制安装mariadb10.2.8
  9. Hive入门学习随笔(二)
  10. 【hdu2588】求[1-n]中和n的gcd大于m的数的个数(求欧拉函数值)
  11. ICS TRIPLEX模块T9110、T8461、T8110B、T8480C、T9110、T9451、T9402、T9432、T9110、T9310-02、1433/09232486825、9100
  12. RedHat Linux各版本汇总
  13. windows下重装系统时驱动备份和恢复命令
  14. Android 使用图片缓存,避免OOM(实现照片墙)
  15. 组装http报文调用小黄鸡网页端消息接口
  16. 上海移动视频客户端 for 8910
  17. Python基于django的图书商城管理系统毕业设计源码110938
  18. 增量式编码器工作原理超详细图解
  19. Android开发-蓝牙遥控器(字符串形式发送)-应用例程
  20. 敏捷项目管理敏捷工作之冲刺计划

热门文章

  1. 两点感悟:关于教育与未来
  2. 和华为hr电话面试的反思
  3. 人终究要活出自己对于这个世界的看法和自己的处事方式,并且由内而外的生成自信
  4. grub2的配置文件grub.cfg详解
  5. JavaScript字符串操作方法大全,包含ES6方法
  6. maven+nexus搭建maven仓库
  7. 【转】如何拿到半数面试公司Offer——我的Python求职之路
  8. tomcat下manager配置
  9. centos重启报错Umounting file systems:umount:/opt:device is busy
  10. 本地连接虚拟机的redis