python ctypes抛出错误?

3 投票
1 回答
2206 浏览
提问于 2025-04-16 13:05

到目前为止,我已经让一个本来不支持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。

撰写回答