標籤:
原文連結:
Python調用C函數 – 快課網
http://www.cricode.com/359.html
關鍵字:Python ctypes,Python調用dll,Python調用C函數
為了節省軟體開發成本,軟體開發人員希望能夠縮短的軟體的開 發時間,希望能夠在短時間內開發出穩定的產品。Python 功能強大,簡單易用,能夠快速開發應用軟體。但是由於 Python 自身執行速度的局限性,對效能要求比較高的模組需要使用效率更高的程式語言進行開發,例如 C 語言,系統的其他模組運用 Python 進行快速開發,最後將 C 語言開發的模組與 Python 開發的模組進行整合。在此背景下,基於 Python 語言與 C 語言的各自特點,用 C 語言來擴充現有的 Python 程式,顯得很有意義。
本文提供Python以連結庫的形式調用C函數的執行個體。主要用到Python提供的ctypes實現。Python官方教程地址:Ctypes
範例一:Python 調用 C 語言 so
第一步:編寫C函數,testlib.c
#include <stdio.h>
void myprint()
{
printf("hello,www.cricode.com!n");
}
第二步:將C函數編譯成連結庫
$ gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c
如果在Mac OS X ,則
$ gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC testlib.c
第三步:在python中使用C連結庫函數,編寫python代碼test.py如下
import ctypes
testlib = ctypes.CDLL(‘/path/to/testlib.so‘)
testlib.myprint()
第四步:just run it
$ python test.py
hello,www.cricode.com!
範例二:參數類型為字串(即傳指標)
當C函數中,參數類型為字串時,使用ctypes提供的create_string_buffer來建立緩衝區。
第一步:編寫C函數testlib1.c
#include <string.h>
int reverse(char* str)
{
int i,j,t;
for(i=0,j=strlen(str) - 1;i<j;i++,j--){
t = str[i];
str[i] = str[j];
str[j] = t;
}
return 0;
}
第二步:將C函數編譯成連結庫
$ gcc -shared -Wl,-soname,testlib1 -o testlib1.so -fPIC testlib1.c
第三步:在python中使用C連結庫函數,編寫python代碼test1.py如下:
import ctypes
s0 = ‘hello,www.cricode.com‘
s1 = ctypes.create_string_buffer(s0)
testlib1 = ctypes.CDLL(‘./testlib1.so‘)
testlib1.reverse(s0)
print ‘s0 is: ‘,s0
print ‘s1 is: ‘,s1.value
第四步:just run it
$ python test1.py
s0 is: moc.edocirc.www,olleh
s1 is: hello,www.cricode.com
範例三:參數為指標、數組(傳指標、數組)
第一步:編寫C函數testlib2.c
void arrayFunc(int *sum,int arr[4])
{
*sum = arr[0]+ arr[1]*2 + arr[2]*3 + arr[3]*4;
}
第二步:將C函數編譯成連結庫
$ gcc -shared -Wl,-soname,testlib2 -o testlib2.so -fPIC testlib2.c
第三步:在python中使用C連結庫函數,
import ctypes
result = ctypes.c_int()
array = ctypes.c_int*4
parray = array(ctypes.c_int(1),ctypes.c_int(2),ctypes.c_int(3),ctypes.c_int(4))
testlib2 = ctypes.CDLL(‘./testlib2.so‘)
#testlib2.arrayFunc.argtypes=[ctypes.c_void_p,ctypes.c_int*4]
testlib2.arrayFunc(ctypes.pointer(result),parray)
print ‘result is:‘,result.value
第四步:just run it
$ python test2.py
result is: 17
範例四 參數為結構體
第一步:編寫C函數testlib3.c
編寫python代碼test2.py如下:
typedef struct{
int x;
int y;
}mystruct;
mystruct structFunc(mystruct a,mystruct b)
{
mystruct s;
s.x = a.x + b.x;
s.y = a.y + b.y;
return s;
}
第二步:將C函數編譯成連結庫
$ gcc -shared -Wl,-soname,testlib3 -o testlib3.so -fPIC testlib3.c
第三步:在python中使用C連結庫函數,編寫python代碼test3.py如下:
import ctypes
class mystruct(ctypes.Structure):
_fields_ = [("x",ctypes.c_int),
("y",ctypes.c_int)]
a = mystruct(2,4)
b = mystruct(4,6)
testlib3 = ctypes.CDLL(‘./testlib3.so‘)
#srestype muste be setted to avoid segment fault
testlib3.structFunc.restype = mystruct
c = testlib3.structFunc(a,b)
print c.x,c.y
第四步:just run it
$ python test3.py
6 10
範例五 回呼函數的使用
回呼函數是什嗎?
回呼函數是由你自己定義,但你永遠也不會調用它的一類函數的總稱。
【也就是說,你是活雷鋒,你在給別人做嫁衣】
continue….
【轉】Python調用C函數