• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

python如何调用c编译好可执行程序

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
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 生成扩展模块分为以下几步:

  1. 将需要调用的代码编译成目标文件(.o) ;
  2. 用SWIG 读取编写描述文件 (.i) ,生成接口文件 (.cxx) ;
  3. 将接口文件编译为目标文件(.o) ;
  4. 将接口文件的目标文件和原代码段的目标文件一起编译成动态库 ;

假设有如下文件

  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 脚本测试框架的很多不足,在提高代码复用率的同时,模块的性能也大大提高。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap