Python: packing an ip address as a ctype.c_ulong() for use with DLL

柔情痞子 提交于 2019-12-06 07:56:54

问题


given the following code:

import ctypes    
ip="192.168.1.1"
thisdll = ctypes.cdll['aDLL']
thisdll.functionThatExpectsAnIP(ip)

how can I correctly pack this for a DLL that expects it as a c_ulong datatype?

I've tried using:

ip_netFrmt = socket.inet_aton(ip)
ip_netFrmt_c = ctypes.c_ulong(ip_netFrmt)

however, the c_ulong() method returns an error because it needs an integer.

is there a way to use struct.pack to accomplish this?


回答1:


The inet_aton returns a string of bytes. This used to be the lingua franca for C-language interfaces.

Here's how to unpack those bytes into a more useful value.

>>> import socket
>>> packed_n= socket.inet_aton("128.0.0.1")
>>> import struct
>>> struct.unpack( "!L", packed_n )
(2147483649L,)
>>> hex(_[0])
'0x80000001L'

This unpacked value can be used with ctypes. The hex thing is just to show you that the unpacked value looks a lot like an IP address.




回答2:


First a disclaimer: This is just an educated guess.

an ip-address is traditionally represented as four bytes - i.e. xxx.xxx.xxx.xxx, but is really a unsigned long. So you should convert the representation 192.168.1.1 to an unsiged int. you could convert it like this.

ip="192.168.1.1"
ip_long = reduce(lambda x,y:x*256+int(y), ip.split('.'), 0)



回答3:


There's probably a better way, but this works:

>>> ip = "192.168.1.1"
>>> struct.unpack('>I', struct.pack('BBBB', *map(int, ip.split('.'))))[0]
3232235777L



回答4:


For a more thorough way of handling IPs (v6, CIDR-style stuff etc) check out how it's done in py-radix, esp. prefix_pton.



来源:https://stackoverflow.com/questions/317531/python-packing-an-ip-address-as-a-ctype-c-ulong-for-use-with-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!