Python ctypes抛出错误?

3

到目前为止,我已经得到了一个不适用于Python的DLL,并使其与Python工作,返回类型:我只是不能传递参数,因为我做错了,并且我不太理解文档上我应该如何做事情。基本上,我正在测试的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.
'''

请在“ndll” dll内说明您要调用的函数的名称和C文档。 - jsbueno
@jsbueno 就像我说的那样,这个函数名叫做“iptouint”,它接受一个双精度浮点数并返回一个字符串。 - pajm
1个回答

2

尝试简单地指定ctypes所需的argtypes以及返回的argtypes:

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值s转换为无符号整数,则返回类型不是您所说的“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安装包使用 - 它可以始终以正确的方式处理这个问题,并且在IPv6方面也可以正常工作。


是的 - 我把我的IP放在插槽里,然后简单地覆盖了它。此外,这个DLL只处理字符串和双精度浮点数。一旦它进入Python,它并没有什么区别。 此外,这只是一个函数。这个DLL实际上是一个网络库,我发现它非常有用,因为它可以读取我需要读取的非常独特的消息。 谢谢您的回复。 :) 我会尝试您建议的方法。 - pajm
等一下 - 这段代码似乎只能与只有一个函数的DLL良好配合使用。我的DLL有很多函数...有没有办法让它保持简单并使用DLL中的所有函数? - pajm
你必须为每个要使用的函数进行装饰,这样CPython才知道要发送哪些参数和接收回来哪些参数。否则,它只会尝试有教养的猜测——比如,“int”表示任何数字,“char_p”表示您传递的任何字符串作为参数(但它将假定函数返回int)。只需为每个要使用的函数设置argtypes和restype即可。 - jsbueno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接