python如何调用c编译好可执行程序
python如何調(diào)用c編譯好可執(zhí)行程序
(2012-08-27 20:34:51) 轉載▼標簽: 雜談 | 分類:學習 |
以下總結出幾種在Python 中調(diào)用 C/C++代碼的方法
--------------------------------------------------------------------
發(fā)現(xiàn)做便捷的是使用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模塊調(diào)用 C 動態(tài)庫
從Python2.5開始, Python 開始提供 ctypes 模塊來提供對 C 語言編譯的動態(tài)庫文件的調(diào)用。注意,?這里特指C 的動態(tài)庫? ,用C++ 編譯的動態(tài)庫 ctypes雖然能夠加載,但調(diào)用時的函數(shù)名已經(jīng)由于 C++ 的重載特性被加以修改,難以調(diào)用。 使用 ctypes 調(diào)用 C動態(tài)庫的好處在于不用進行額外的開發(fā),可以直接使用編譯好的動態(tài)庫。 ctypes 提供了完整的 C類型封裝,也支持自定義類型,大大減少在調(diào)用過程中的工作量。ctypes 的使用很簡單,只需熟悉 python 封裝與 C 中的對應關系即可。以下用一個簡單的例子來說明:
from?ctypes? import? *#導入ctypes模塊
libc= cdll.LoadLibrary("libc.so.6") #加載libc動態(tài)庫
str?= c_char_p(' Hello World! ') #使用char*在ctypes中的對應封裝c_char_p,相當于char* str=”Hello World!”
libc.printf(“yell:%s\n”,? str ) #調(diào)用printf函數(shù)
ctypes的功能當然遠不止這些,有興趣的同學可以參考這里http://docs.python.org/library/ctypes.html
使用Python的擴展( Extending )機制
ctypes很方便地可以調(diào)用C 的動態(tài)庫,但是對 C++ 編譯的動態(tài)庫,調(diào)用起來很困難。這種情況利用 Python 的 Extending 機制就可以解決。Python 提供了一套完整的框架來使用 C/C++ 編寫擴展庫,可以很靈活的開發(fā) C++擴展模塊。這種方法的缺點是工作量比較大,需要為每一個方法編寫接口,這里不做詳細介紹,可以參考:http://docs.python.org/extending/extending.html#writing-extensions-in-c
那么有什么辦法可以高效的調(diào)用C++動態(tài)庫呢,答案是 SWIG 。
使用SWIG生成擴展模塊
上面提到了Python的擴展機制,缺點是工作量比較大,這里介紹一個工具 SWIG 。 SWIG 是一種簡化腳本語言與 C/C++接口的開發(fā)工具,通過包裝和編譯 C 語言程序來達到與腳本語言通訊目的的工具。它正是基于 Python的擴展機制,自動生成接口文件,再編譯成可以被 Python 調(diào)用的動態(tài)庫擴展模塊。
使用SWIG生成擴展模塊分為以下幾步:
假設有如下文件
swig_ex.cpp需要轉換成擴展庫的原始代碼,包含一個int fact(int) 函數(shù)
swig_ex.h?原始代碼的頭文件
swig_ex.iSWIG描述文件
swig_ex.i是一個描述文件,有SWIG 自己的語法,比較簡單,內(nèi)容如下:
?
| %moduleswig_ex %{ ???#define SWIG_FILE_WITH_INIT ???#include "swig_ex.h" %} intfact(int n); |
再寫一個Makefile來把這些文件編譯成動態(tài)庫 :
?
| 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 #根據(jù) 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 #將目標文件打包成動態(tài)庫 ??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調(diào)用了:
?
| Importswig_ex swig_ex.fact(10) |
參考文檔地址:http://www.swig.org/Doc1.3/SWIGDocumentation.html
原始但有效的方法
除了上面這些方法,在Python中借用 C/C++ 代碼最原始有效的方法就是將代碼編譯成可執(zhí)行程序,從 Python 里用 Popen方法來調(diào)用獲取輸出。這種方法簡單有效,缺點是不夠靈活,有比較大的局限性,不過在很多情況下也已經(jīng)足夠了。
?
| pipe =os.popen('./tool –a %s –b %s' % (“hello”,“world”)) re =pipe.read() |
其他方法
以上這些方法基本上已經(jīng)能滿足Python調(diào)用 C/C++ 的需求了,此外還有一些方法,例如使用 Boost.Python ,使用 Pyrex ,這些方法都能提供 Python與 C/C++ 的交互。
總結
在Python中引用 C/C++ 模塊的方法較多,根據(jù)需要從中選擇恰當?shù)姆椒梢詼p少很多工作量。
在Python中引用 C/C++ 模塊彌補了 Python腳本測試框架的很多不足,在提高代碼復用率的同時,模塊的性能也大大提高。
總結
以上是生活随笔為你收集整理的python如何调用c编译好可执行程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 纯Python包发布setup脚本编写示
- 下一篇: python调用可执行文件