ctypes提供了两个LibraryLoader:CDLL和WinDLL。
CDLL支持__cdecl,WinDLL支持__stdcall(仅限Windows)。
根据您在C库中使用的调用约定,您必须在Python中使用正确的LibraryLoader。
import ctypes as C
try:
lib = C.CDLL('/lib.dll')
except:
try:
lib = C.WinDLL('/lib.dll')
except:
print 'failed to load lib'
这段代码永远不会在Windows上运行,因为ctypes是一个惰性加载器,这意味着当你加载库时,他不会检查你选择的LibraryLoader是否匹配C库中的调用约定。
因此,您可以在python中加载一个使用__stdcall和CDLL的C库,并且ctypes不会引发任何错误。
只是在您尝试调用该C库中的函数时,ctypes将引发以下错误。
ValueError: Procedure called with not enough arguments (4 bytes missing) or wrong calling convention
这意味着您应该使用WinDLL而不是CDLL,反之亦然。
因为ctypes是一个懒惰的加载器,所以要确保使用正确的加载程序,具体取决于C库中使用的调用约定。
附录:python 类型转换的坑
bytes to string
>>> b"abcde".decode("utf-8")
'abcde'
string to bytes
>>> "abcde".encode("utf-8")
b'abcde'
str to char *
string1 = "my string 1"
string2 = "my string 2"
# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')
# send strings to c function
my_c_function(ctypes.c_char_p(b_string1),
ctypes.c_char_p(b_string2))
通过多次尝试,我发现可以通过设置API的restype来获得正确的内存地址。
create_string_buffer(3) 是初始化 char 和 char * buffer
网友评论