![](/img/trans.png)
[英]strtod returns wrong value when called from Python ctypes and run from Spyder or Pyzo
[英]C function called from Python via ctypes returns incorrect value
我在 C 中編寫了一個簡單的 function ,它將給定的數字提高到給定的功率。 當我在 C 中調用它時,function 返回正確的值,但是當我在 Python 中調用它時,它返回一個不同的、不正確的值。
我使用以下命令創建了共享文件: $ gcc -fPIC -shared -o test.so test.c
我嘗試了 C function 的不同配置,其中一些返回預期值,而另一些則沒有。 例如,當我的 function 使用return x*x
一個簡單的正方形時,沒有for
循環,它在 Python 中返回了正確的值。
我希望最終能夠在 python 中調用 C function ,它將返回一個二維 Z0D6178370CAD1D4E12F 數組。
#include <stdio.h>
float power(float x, int exponent)
{
float val = x;
for(int i=1; i<exponent; i++){
val = val*x;
}
return val;
}
from ctypes import *
so_file = '/Users/.../test.so'
functions = CDLL(so_file)
functions.power.argtype = [c_float, c_int]
functions.power.restype = c_float
print(functions.power(5,3))
I obtain the expected output of 125.0 when I call the function in C, but when I call the function in python, it returns a value of 0.0.
這是我第一次使用 ctypes。 我是否犯了一個明顯的錯誤導致 function 計算錯誤?
清單[Python 3.Docs]:ctypes - 用於 Python 的外部 function 庫。
In order for everything to be properly converted ( Python <=> C ) when calling the function (residing in a .dll ( .so )), 2 things need to be specified (leaving x86 calling convention ( Win ) aside):
在CTypes中,這是通過指定:
旁注:上述方法的替代方法是對外部函數進行原型設計( CFUNCTYPE 、 WINFUNCTYPE 、 PYFUNCTYPE - 檢查Function 原型部分(在開頭的URL中))。
反正:
它們中的任何一個(如果需要(1) )將導致應用默認值:所有都被視為( C89風格) int s,它(在大多數系統上)是32位長。
這會產生未定義的行為(2) (在錯誤指定它們時也適用),尤其是在64 位CPU / OS上,其中較大類型的值(例如指針)可能會被截斷。
顯示的錯誤可能很多,有時會產生誤導。
您拼錯了argtype (末尾缺少s )。
糾正一下,你應該沒問題
示例:
對於由libdll.dll ( libdll.so ) 導出的 function函數,具有以下 header:
double func(uint32_t ui, float f, long long vll[8], void *pv, char *pc);
Python等效項為:
func = libdll.func
func.argtypes = (ctypes.c_uint32, ctypes.c_float, ctypes.c_longlong * 8, ctypes.c_void_p, ctypes.POINTER(ctypes.c_char))
'''
It would be a lot easier (nicer, and in most cases recommended)
the last element to be ctypes.c_char_p,
but I chose this form to illustrate pointers in general.
'''
func.restype = ctypes.c_double
相同(或非常相似)場景的一些(更具破壞性)結果(還有很多其他):
#1 :從技術上講,有些情況不需要指定它們。 但即便如此,最好指定它們以消除任何可能的混淆:
Function 沒有 arguments:
function_from_dll.argtypes = ()
Function 返回void :
function_from_dll.restype = None
#2 : Undefined Behavior ( [Wikipedia]: Undefined behavior ) 顧名思義,是一段代碼的結果無法“預測”(或保證)的情況。 主要案例:
它的“美”在於有時它看起來完全隨機,有時它在某些特定情況下(不同的機器、不同的操作系統、不同的環境......)“只復制”。 歸根結底,所有這些純屬巧合! 問題在於代碼(可能是當前代碼(最高機會)或它使用的其他代碼(庫、編譯器))。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.