使用C语言扩展Python(一)

开发环境:Ubuntu9.10,python2.6,gcc4.4.1

1,ubuntu下的python运行包和开发包是分开的,因此需要在新利得里面安装python-all-dev,从而可以在代码中引用python的头文件和库。

2.下面是一个最简单的可以供python调用的c扩展模块,假设c程序文件名为foo.c:

复制代码

代码

#include <Python.h>

static PyObject* foo_bar(PyObject* self, PyObject* args) {

Py_RETURN_NONE;

}

static PyMethodDef foo_methods[] = {

{"bar",(PyCFunction)foo_bar,METH_NOARGS,NULL},

{NULL,NULL,0,NULL}

};

PyMODINIT_FUNC initfoo() {

Py_InitModule3("foo", foo_methods, "My first extension module.");

}

复制代码

我们可以将上述模块分成3个部分:1)c模块想对外暴露的接口函数。2)提供给外部的python程序使用的一个c模块函数名称映射表。3)c模块的初始化函数。模块的第一行将Python.h引入到模块中,这个文件将使得你的模块可以hook进python的解释器,从而可以为外部的python程序所使用。

c模块中的函数签名一般有下列三种形式:

PyObject* MyFunction(PyObject* self, PyObject* args);

PyObject* MyFunctionWithKeywords(PyObject* self, PyObject* args, PyObject* kw);

PyObject* MyFunctionWithNoArgs(PyObject* self);

一般我们使用的是第一种方式,函数的参数将会一个元组(tuple)的形式传进来,因此我们在c模块的函数中需要对其进行解析。Python中不能象c语言一样声明一个void类型的函数,如果你不想函数返回一个值的话,那就返回一个NONE,在这里我们可以通过Python头文件中的一个宏Py_RETURN_NONE来实现。

C模块中的函数名称其实对外部来说是不可见的,因此可以随便你命名,一般我们可以使用static函数(这在C语言里表示在当前文件以外是不可见的)。本文函数命名方式采用模块名加上函数名,例如foo_bar,这表示在模块foo中会有一个bar函数。然后就是函数映射表了,它是一个PyMethodDef结构体数组,

struct PyMethodDef {

char* ml_name;

PyCFunction ml_meth;

int ml_flags;

char* ml_doc;

};

第一个成员ml_name是函数名,当我们在外部的Python代码中使用此模块时利用这个名称进行函数调用。ml_meth是函数地址。ml_flags告诉解释器ml_meth将会使用上述三种方法签名的哪一种,一般设置为METH_VARARGS,如果你想允许关键字参数,则可以将其与METH_KEYWORDS进行或运算。若不想接受任何参数,则可以将其设置为METH_NOARGS.最后,ml_doc字段是函数的注释文档信息,最好还是写几句吧,不然会被鄙视的。。。另外,这个表必须以{NULL,NULL,0,NULL}这样一条空记录结尾。

模块的初始化函数是在模块被加载时被Python解释器所调用的,如果你的模块名为foo,则要求命名为initfoo.Py_InitModule3函数一般用来定义一个模块。

3,现在我们来将foo.c文件编译为一个扩展模块,使用下述命令进行编译:

gcc -shared -I /usr/include/python2.6 foo.c -o foo.so

注意shared object的名称必须和传给Py_InitModule3函数的字符串一致,另一种可选的方式是加上module后缀,因此上述foo模块可以命名为foo.so或foomodule.so。

4,上面的编译方式可以完成任务,但更好的生成扩展模块的方法是使用distutils。首先写一个setup.py脚本:

from distutils.core import setup, Extension

setup(name = 'foo', version = '1.0', ext_modules = [Extension('foo', ['foo.c'])])

然后执行下述命令进行build:

python ./setup.py build

这会在当前目录下生成一个build子目录,其中包含了中间生成的foo.o以及最后生成出来的foo.so。当然,最简单的方法是使用下述命令进行模块的生成和安装:

python ./setup.py install

注:由于需要获得dist-packages的写权限,最好先切换到root用户,如果直接使用su切换出现下面的错误:

su: Authentication failure

则为root用户设置一个新密码:

sudo passwd root

再用新密码切换到root用户。查看build时的详细情况,我们可以发现这么一句:

copying build/lib.linux-i686-2.6/foo.so -> /usr/local/lib/python2.6/dist-packages

这是将生成的模块拷贝到/usr/local/lib/python2.6/dist-packages下了,这样就将我们的foo模块安装到系统中了,我们可以验证如下,在python命令行中,

import foo

dir(foo)

结果如下:

['__doc__','__file__','__name__','__package__','bar']

呵呵,不错吧,这个foo模块现在已经和其他系统模块一样了,原因就在于dist-packages是在sys.path这个路径中的,

5,现在我们手上已经有一个生成并安装好的C扩展模块了,剩下的就是在python代码中引入这个新模块,并调用它的方法

import foo

foo.bar()

当然,由于在c模块中的bar函数里,我们目前什么都还没做,所以现在啥都没有,在下一篇中我们实现:1)从python脚本里向C模块中传递参数。2)从C模块中返回值给外部的Python脚本

夜已经深了,这个python和c/c++,java相结合系列的第一篇就暂时写到这里。。。

本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2010/05/17/1737033.html,如需转载请自行联系原作者

文章

C语言 · Python · C++ · Java · Ubuntu

2018-01-07

python电子签章_签名python的搜索结果-阿里云开发者社区相关推荐

  1. python妹子图_python 妹子图的搜索结果-阿里云开发者社区

    Python老司机手把手带你写爬虫,整站下载妹子图,一次爽个够! 其实很多编程语言都可以做爬虫,例如java.c#.php等等甚至excel都可以抓网页的图表,那么为什么我们要用Python呢?它简单 ...

  2. mysql slave是什么_创建slave的搜索结果-阿里云开发者社区

    Rainbond部署Mysql主从集群应用说明 Mysql主从同步原理 1)在Slave 服务器上执行sart slave命令开启主从复制开关,开始进行主从复制. 2)此时,Slave服务器的IO线程 ...

  3. mysql inserted表_数据库inserted的搜索结果-阿里云开发者社区

    SQL 2000中的触发器使用 触发器是数据库应用中的重用工具,它的应用很广泛,这几天写一个化学数据统计方面的软件,需要根据采样,自动计算方差,在这里,我使用了触发器. 下面我摘录了SQL Serve ...

  4. python读取mssql文件_python 读取mssql数据库中文的搜索结果-阿里云开发者社区

    sphinx 配置文件全解析 sphinx的配置文件是在配置的时候最容易出错的了: 我们先要明白几个概念: source:数据源,数据是从什么地方来的. index:索引,当有数据源之后,从数据源处构 ...

  5. 如何阅读python文档_python 文档怎么看-问答-阿里云开发者社区-阿里云

    调用help函数,可以看到一个函数或者方法的字符串文档. In [1]: import requests In [2]: help(requests.get) Help on function get ...

  6. oss 视频 转码_播放oss问题的搜索结果-阿里云开发者社区

    OSS 咨询 作者:张医博 浅谈 本章介绍一些基本的 oss 的咨询内容,问题是一直在补充的,不定期的进行更新: 问:cdn 结合 oss,oss 地址被暴露后如何处理 答: 暴露后无法组织别人访问你 ...

  7. 大数据中心成立ppt_云计算数据中心 ppt的搜索结果-阿里云开发者社区

    [0713 - 0717 直播导视 | PPT 下载]新品众星云集:阿里云存储新品发布会.mPaaS 小程序新品发布会.阿里云ECS新品发布会 *本预告时间仅供参考,最终直播时间以直播间信息为准.*本 ...

  8. python调用 matlab库_python调用matlab的搜索结果-阿里云开发者社区

    2018python技术问答集锦,希望能给喜欢python的同学一些帮助 小编发现问答专区中有很多人在问关于python的问题,小编把这些问题汇总一下,希望能给喜欢python的大家一些启示和帮助 本 ...

  9. python预测实例教程_手把手教你用Python库Keras做预测(附代码)-阿里云开发者社区...

    当你在Keras中选择好最合适的深度学习模型,就可以用它在新的数据实例上做预测了.但是很多初学者不知道该怎样做好这一点,我经常能看到下面这样的问题: "我应该如何用Keras对我的模型作出预 ...

最新文章

  1. BigDecimal类(精度计算类)的加减乘除
  2. TEdit扩展:做成多按钮的Edit,可用作浏览器地址栏
  3. 华为云内容审核—性能更加狂野,价格更加腼腆
  4. c16语言延时函数delay,《linux设备驱动开发详解》笔记——10中断与时钟
  5. 解压ubi文件_请问为什么AM3352 NAND FLASH UBI文件系统挂载失败?
  6. 转:Java多线程学习(吐血超详细总结)
  7. Python数据挖掘工具总结
  8. CorelDRAW暗角效果怎么做?
  9. MySQL - 实战 棋牌游戏数据库开发
  10. 基于BB方案,荣耀观影眼镜Vision Glass正式发布
  11. 光猫 路由器 和交换器
  12. jntoo.php,admin/website.php · 曹琪/shufadasai-englishi - Gitee.com
  13. 2020年汽车驾驶员(初级)考试平台及汽车驾驶员(初级)模拟考试软件
  14. python:split()函数
  15. beautifulsoup函数
  16. 配置sumlime html,Sublime Text 3使用SublimeLinter配置JS,CSS,HTML语法检查
  17. 更改tkinter的OptionMenu背景颜色和下拉菜单宽度
  18. java基础(1)—1
  19. 中央批准!985大学,迎来院士校长(副部长级)
  20. php自带加密解密函数

热门文章

  1. bpmn-process-designer基础上进行自定义样式(工具、元素、菜单)
  2. 华为鸿蒙系统与麒麟系统,搭载鸿蒙系统,麒麟9000处理器
  3. HDU 5669 Road(线段树建树)(分层图最短路)
  4. Crayon:新研究指出让IT决策者夜不能寐的原因
  5. 稳压二极管工作原理、重要参数意义和典型电路参数计算
  6. 终端安全产品哪家强?
  7. 三种经典图像滤波方法介绍——双边滤波(Bilateral filter)、导向滤波(Guided Fliter)、滚动导向滤波(RollingGuidedFilter)
  8. 基于电力线载波的物联网智能家居控制系统研究方案
  9. 南宁计算机专业学校排名,学校排名
  10. 武汉某GIS企业机试题