python如何调用c编译好可执行程序
以下总结出几种在Python 中调用 C/C++ 代码的方法
--------------------------------------------------------------------
发现做便捷的是使用popen
from os import popen
popen('/home/pengyan/Downloads/VIC/sanxia/vicNl -g /home/pengyan/Downloads/VIC/sanxia/xings_global')
popen('/home/pengyan/Downloads/VIC/sanxia/rout /home/pengyan/Downloads/VIC/sanxia/xings_rout')
?? 目前还不会用python 切换文件目录
可以采用绝对路径,但是好像绝对路径时,计算速度变慢
-------------------------------------------------------------------
使用ctypes 模块调用 C 动态库
从Python2.5 开始, Python 开始提供 ctypes 模块来提供对 C 语言编译的动态库文件的调用。注意, 这里特指C 的动态库 ,用C++ 编译的动态库 ctypes 虽然能够加载,但调用时的函数名已经由于 C++ 的重载特性被加以修改,难以调用。 使用 ctypes 调用 C 动态库的好处在于不用进行额外的开发,可以直接使用编译好的动态库。 ctypes 提供了完整的 C 类型封装,也支持自定义类型,大大减少在调用过程中的工作量。 ctypes 的使用很简单,只需熟悉 python 封装与 C 中的对应关系即可。以下用一个简单的例子来说明:
from ctypes import * #导入ctypes模块
libc = cdll.LoadLibrary("libc.so.6") #加载libc动态库
str = c_char_p(' Hello World! ') #使用char *在ctypes中的对应封装c_char_p,相当于char* str=”Hello World!”
libc.printf(“yell: %s\n”, str ) #调用printf函数
ctypes的功能当然远不止这些,有兴趣的同学可以参考这里 http://docs.python.org/library/ctypes.html
使用Python 的扩展( Extending )机制
ctypes很方便地可以调用 C 的动态库,但是对 C++ 编译的动态库,调用起来很困难。这种情况利用 Python 的 Extending 机制就可以解决。 Python 提供了一套完整的框架来使用 C/C++ 编写扩展库,可以很灵活的开发 C++ 扩展模块。这种方法的缺点是工作量比较大,需要为每一个方法编写接口,这里不做详细介绍,可以参考: http://docs.python.org/extending/extending.html#writing-extensions-in-c
那么有什么办法可以高效的调用C++ 动态库呢,答案是 SWIG 。
使用SWIG 生成扩展模块
上面提到了Python 的扩展机制,缺点是工作量比较大,这里介绍一个工具 SWIG 。 SWIG 是一种简化脚本语言与 C/C++ 接口的开发工具,通过包装和编译 C 语言程序来达到与脚本语言通讯目的的工具。它正是基于 Python 的扩展机制,自动生成接口文件,再编译成可以被 Python 调用的动态库扩展模块。
使用SWIG 生成扩展模块分为以下几步:
- 将需要调用的代码编译成目标文件(.o) ;
- 用SWIG 读取编写描述文件 (.i) ,生成接口文件 (.cxx) ;
- 将接口文件编译为目标文件(.o) ;
- 将接口文件的目标文件和原代码段的目标文件一起编译成动态库 ;
假设有如下文件
swig_ex.cpp 需要转换成扩展库的原始代码,包含一个int fact(int) 函数
swig_ex.h 原始代码的头文件
swig_ex.i SWIG描述文件
swig_ex.i是一个描述文件,有 SWIG 自己的语法,比较简单,内容如下:
%module swig_ex %{ #define SWIG_FILE_WITH_INIT #include "swig_ex.h" %} int fact(int n); |
再写一个Makefile 来把这些文件编译成动态库 :
all: swig_ex.o swig_ex_wrap.o _swig_ex.so swig_ex.o: swig_ex.cpp swig_ex.h #编译源文件 g++ -fPIC -c swig_ex.cpp swig_ex_wrap.o: swig_ex.i swig_ex.o #根据 SWIG 描述文件 (.i) 生成接口文件 (.cxx) ,再编译之 swig -c++ -python swig_ex.i g++ -O2 -fPIC -c swig_ex_wrap.cxx -I/home/work/linyi/autoframe/tool/python/include/python2.6/ _swig_ex.so: swig_ex_wrap.o #将目标文件打包成动态库 g++ -shared swig_ex.o swig_ex_wrap.o -o _swig_ex.so .PHONY: clean clean: rm -rf swig_ex_wrap.* swig_ex.py _swig_ex.so |
编译好以后会有一个so 和 py 文件,写一个 setup.py 把他们安装到 python 目录就可以和其他模块一样被 python 调用了:
Import swig_ex swig_ex.fact(10) |
参考文档地址:http://www.swig.org/Doc1.3/SWIGDocumentation.html
原始但有效的方法
除了上面这些方法,在Python 中借用 C/C++ 代码最原始有效的方法就是将代码编译成可执行程序,从 Python 里用 Popen 方法来调用获取输出。这种方法简单有效,缺点是不够灵活,有比较大的局限性,不过在很多情况下也已经足够了。
pipe = os.popen('./tool –a %s –b %s' % (“hello”, “world”)) re = pipe.read() |
其他方法
以上这些方法基本上已经能满足Python 调用 C/C++ 的需求了,此外还有一些方法,例如使用 Boost.Python ,使用 Pyrex ,这些方法都能提供 Python 与 C/C++ 的交互。
总结
在Python 中引用 C/C++ 模块的方法较多,根据需要从中选择恰当的方法可以减少很多工作量。
在Python 中引用 C/C++ 模块弥补了 Python 脚本测试框架的很多不足,在提高代码复用率的同时,模块的性能也大大提高。
python如何调用c编译好可执行程序的更多相关文章
- 在python里调用java的py4j的使用方法
py4j可以使python和java互调 py4j并不会开启jvm,需要先启动jvm server,然后再使用python的client去连接jvm GatewayServer实例:允许python程 ...
- 如何在python中调用C语言代码
1.使用C扩展CPython还为开发者实现了一个有趣的特性,使用Python可以轻松调用C代码 开发者有三种方法可以在自己的Python代码中来调用C编写的函数-ctypes,SWIG,Python/ ...
- 使用ctypes在Python中调用C++动态库
使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #in ...
- Python基础笔记系列十四:python无缝调用c程序
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python语言可以对c程序代码进行调用,以弥补python语言低性能的缺 ...
- Python 下调用C动态链接库 -- (转)
在linux开发的动态链接库需要被python调用,首先需要生成.so文件. 生成动态链接库的方法网上有很多,主要就是首先根据源文件编译生成.o,然后链接这些.o文件-shared生成.so.需要注意 ...
- python程序调用C/C++代码
这篇用来记录在些模拟Canoe生成CAN数据桢工具时遇到的问题, 生成CAN数据桢,主要分为两个关注点: 1.如何从can信号名获取到can信号的ID长度以及信号的起始位,并将信号值按照一定的规则填写 ...
- python下调用c语言代码
1)首先,创建一个.c文件,其大体内容如下: 2 #include <Python.h> 99 char * extract(char * path) ...
- SQLite 版本引发的 Python 程序调用问题
问题 在跑 OpenStack functional 功能测试的时候有两个用例过不去. nova.tests.functional.db.test_resource_provider.Resource ...
- 使用PyQt(Python+Qt)+动态编译36行代码实现的计算器
PyQt是基于跨平台的图形界面C++开发工具Qt加Python包装的一个GPL软件(GPL是GNU General Public License的缩写,是GNU通用公共授权非正式的中文翻译),Qt基于 ...
随机推荐
- iOS OC中桥接swift第三方库
swift中有一些比较好的框架,比如绘图框架charts,最近项目中刚好用到,通过Pod的方式直接导入,xcode会自动生成charts-swift.h的文件,然后在需要导入的地方import < ...
- (转)深入理解Java:注解(Annotation)自定义注解入门
向作者致敬! 转自:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在 ...
- OpenStack Nova 高性能虚拟机之 CPU 绑定
目录 文章目录 目录 前文列表 KVM KVM 的功能列表 KVM 工具集 KVM 虚拟机的本质是什么 vCPU 的调度与性能问题 Nova 支持的 vCPU 绑定 vcpu\_pin\_set 配置 ...
- TCP 首部格式
<图解TCP/IP> 6.7 TCP的首部格式 TCP中没有表示包长度和数据长度的字段.可由IP层获知TCP的包长由TCP的包长可知数据的长度. 源端口号:表示发送端端口号,字段长16位 ...
- EFI系统分区如何删除
U盘或者硬盘被做了系统安装盘. 结果在格式化都是失败,分区也不行. 有了新招 EFI分区是您的系统启动引导的分区,存放引导启动的文件的,因此它是一个操作系统独立的分区,实际上它是UEFI加载的固件和应 ...
- xmake新增对Cuda代码编译支持
最近研究了下NVIDIA Cuda Toolkit的编译环境,并且在xmake 2.1.10开发版中,新增了对cuda编译环境的支持,可以直接编译*.cu代码. 关于Cuda Toolkit相关说明以 ...
- eclipse sts 快捷键
1. ctrl + m 全屏/取消全屏 2.快速切换上面标签 ctrl + pageup/pagedown : 标签左右切换 ctrl + < > : 标签前后访问处切换 New Ja ...
- Dubbo原理学习
Dubbo源码及原理学习 阿里中间件团队博客 Dubbo官网 Dubbo源码解析 Dubbo源码解析-掘金 Dubbo源码解析-赵计刚 Dubbo系列 源码总结+最近感悟
- [知乎]ARM 到底是什么
[小宅按]近期公司推出来基于ARM芯片的服务器,本文就一些基本概念,比如ARM, ARM64, ARMv8, ARM7,ARMv7, 64位等让人费解的概念进行了粗浅地分析,涉及的关键字已用粗体标出. ...
- python字符串 常用函数 格式化字符串 字符串替换 制表符 换行符 删除空白 国际货币格式
# 字符串常用函数# 转大写print('bmw'.upper()) # BMW# 转小写print('BMW'.lower()) # bmw# 首字母大写print('how aae you ?'. ...