Python: ctypes CDLL 和 WinDLL区别

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))

ctypes 文档

通过多次尝试,我发现可以通过设置API的restype来获得正确的内存地址。
create_string_buffer(3) 是初始化 char 和 char * buffer

发布了121 篇原创文章 · 获赞 54 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/wm9028/article/details/100889345