python ctypes抛出错误?
到目前为止,我已经让一个本来不支持Python的DLL可以工作了,并且也能返回类型。但我就是无法正确传递参数,因为我做错了,而且对文档的理解也不太清楚。我正在测试的这个DLL里的函数叫“iptouint”。它需要一个c_char_p类型的参数,并返回一个c_double类型的结果。
这是我的代码:
nDll = ctypes.WinDLL('ndll.dll')
nDllProto = ctypes.WINFUNCTYPE(ctypes.c_double)
nDllInit = nDllProto(("dllInit", nDll))
nDllTestProto = ctypes.WINFUNCTYPE(ctypes.c_double,ctypes.c_char_p)
nDllTest = nDllTestProto(("iptouint",nDll),((1, "p1",0),(1, "p2",0)))
#This is the line that throws the error:
print("IP: %s" % nDllTest("12.345.67.890"))
'''
It gives me the error:
ValueError: paramflags must have the same length as argtypes
Im not sure what to do; Ive certainly played around with it to no avail.
Help is much appreciated.
Thanks.
'''
1 个回答
2
试着简单地告诉ctypes它需要的参数类型和返回的类型:
nDll = ctypes.WinDLL('ndll.dll')
nDll.restype = ctypes.c_double
nDll.argtypes = [ctypes.c_char_p]
result = nDll.iptouint("12.345.67.890").value
不过,考虑以下几点:
1) 如果这个函数的名字说明它是把一个字符串形式的IPv4值转换成无符号整数,那么返回的类型并不是你说的“double”,而应该是ctypes.c_uint32。
2) 你给出的示例值并不是一个有效的IPv4地址,无法转换成32位整数(也不可能是“double”,即64位浮点数)——它根本就是无效的。
3) 如果你只是想在Python中得到一个无符号的32位值来表示IPv4地址,其实不需要这样做。有很多更简单、更易读的方法可以用纯Python实现,而且这些方法在不同平台上都能用。例如:
def iptoint(ip):
value = 0
for component in ip.split("."):
value <<= 8 #shifts previous value 8 bits to the left,
#leaving space for the next byte
value |= int(component) # sets the bits for the new byte in the address
return value
更新:在Python 3.x中有一个ipaddress模块 - https://docs.python.org/3/library/ipaddress.html - 这个模块在Python 2.x中也可以通过pip安装,它可以始终以正确的方式处理IPv4和IPv6。