2016-10-18 21 views
11

我已經嘗試過在互聯網上提到的所有解決方案,至今沒有爲我工作。在Python中使用C函數

我有一個python代碼,爲了加快速度,我希望我的代碼在C函數中運行繁重的計算。 我已經寫了這個C函數。

然後,共享庫,我在終端做:

gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC myModule.c 

返回任何錯誤。問題;當我嘗試在python中啓動C函數時出現。讓我們考慮下面這個簡單的功能在C:

int multiplier(int a, int b) 
{ 

int lol = 0; 

lol = a*b; 

return lol; 
} 

我啓動python3(3.5.2),然後輸入:

import ctypes 
zelib = ctypes.CDLL("/Users/longeard/Desktop/Codes/DraII/testlib.so",ctypes.RTLD_GLOBAL) 

圖書館應準備做在Python中使用:

res = zelib.multiplier(2,3) 

如果這樣做,它的工作原理和python回報

6 

問題是,我想使用的函數(我使用的乘數函數僅用於示例)應該將浮點數作爲輸入並返回一個浮點數。但是,如果我現在考慮同樣的倍增器功能之前,但使用float:

float multiplier(float a, float b) 
{ 

float lol = 0.0; 

lol = a*b; 

return lol; 
} 

我重新編譯使用gcc,我重新導入的ctypes和重新做ctypes.CDLL,我做python3:

zelib.multiplier(ctypes.c_float(2),ctypes.c_float(3)) 

(在types.c_float在這裏向2轉換在python成在C浮動),蟒蛇將返回:

2 

這是奇怪的,因爲如果我添加功能中一個printf打印笑,Python會打印:

6.0 

但仍然返回2或18有時。即使我printf並返回相同的變量「哈哈」。

我嘗試了很多東西,但都沒有成功。請有人有想法嗎?謝謝。

回答

2

雖然@ falsetru的回答是這樣做的更好的方式替代是簡單地寫你的C函數使用雙打。

當調用沒有參數列表的函數時,浮點數自動提升爲double。

7

你需要指定restypeargtypes功能:

zelib = ctypes.CDLL('...') 
zelib.multiplier.restype = ctypes.c_float # return type 
zelib.multiplier.argtypes = [ctypes.c_float, ctypes.c_float] # argument types 

根據Specifying the required argument types (function prototypes)

有可能通過設置argtypes指定所需的參數類型的dll的導出函數屬性。在ctypes module documentation

Return types

默認情況下的函數都返回c的int類型。其他返回類型可以通過設置函數對象的restype屬性來指定。


# without specifying types 
>>> import ctypes 
>>> zelib = ctypes.CDLL('testlib.so') 
>>> zelib.multiplier(2, 3) 
0 

# specifying types 
>>> zelib.multiplier.restype = ctypes.c_float 
>>> zelib.multiplier.argtypes = [ctypes.c_float, ctypes.c_float] 
>>> zelib.multiplier(2, 3) 
6.0 
+1

謝謝你,作品像一個魅力!我昨天曾多次嘗試過,因爲某種原因,它不起作用,但現在它確實有效。 – Nicano

+0

對不起,雙重評論....你碰巧知道如何通過numpy浮點數組作爲輸入在這種情況下?並在C函數中返回一個數組?謝謝。 – Nicano

+0

@Nicano,看看這個:http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.ctypes.html如果你有更多的問題,請把它作爲另一個問題。 – falsetru