2012-09-12 37 views
4

我與ctypes的玩弄......我有以下的C代碼Python的INT溢出調用

編輯 ctypes的功能時:我試圖算出這個的原因是爲了讓更多的this blog post正確

sumrange.c

#include <stdio.h> 

long sumrange(long); 

long sumrange(long arg) 
{ 
    long i, x; 
    x = 0L; 

    for (i = 0L; i < arg; i++) { 
     x = x + i; 
    } 
    return x; 
} 

我編譯使用(在OSX)

$ gcc -shared -Wl,-install_name,sumrange.so -o ./sumrange.so -fPIC ./sumrange.c 
01下面的命令

我實現了同樣的功能在Python:

pysumrange = lambda arg: sum(xrange(arg)) 

後來我在交互shell中運行兩個:

>>> import ctypes 
>>> sumrange = ctypes.CDLL('./sumrange.so') 
>>> pysumrange = lambda arg: sum(xrange(arg)) 
>>> print sumrange.sumrange(10**8), pysumrange(10**8) 
... 887459712 4999999950000000 

...和號碼不匹配。爲什麼會這樣?

我試着對C代碼中的所有變量使用unsigned long long而沒有任何效果(相同的輸出)。

+1

爲您的博客後,我用了一個numpy的版本,它Python和C. –

+0

相關介於很好: http://stackoverflow.com/questions/23522055/error-when-unload-a-64bit-dll-using-ctypes-windll –

回答

4

long是一個32位的類型,所以C代碼只是溢出。

Python不; pysumrange給你正確的答案。

​​不知道函數的返回類型是unsigned long long,除非您告訴它。請參閱Python標準庫文檔中的return types。它說:

默認情況下,功能被假定爲返回C int類型。其他返回類型可以通過設置函數對象的restype屬性來指定。

因此,也許這樣做,只需調用函數之前,會爲你工作:

sumrange.sumrange.restype = ctypes.c_ulonglong 
+2

這也是一個很好的做法,爲ctypes函數設置argtypes。 'sumrange.sumrange.argtypes = [ctypes.c_long]' –