Pregunta

dado el siguiente código:

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

¿cómo puedo empaquetar esto correctamente para una DLL que lo espera como un tipo de datos c_ulong?

He intentado usar:

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

sin embargo, el método c_ulong () devuelve un error porque necesita un número entero.

¿hay alguna manera de usar struct.pack para lograr esto?

¿Fue útil?

Solución

El inet_aton devuelve una cadena de bytes. Solía ??ser la lingua franca para las interfaces de lenguaje C.

Aquí se explica cómo descomprimir esos bytes en un valor más útil.

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

Este valor desempaquetado se puede usar con ctypes. Lo hexadecimal es solo para mostrarle que el valor desempaquetado se parece mucho a una dirección IP.

Otros consejos

Primero un descargo de responsabilidad: esto es solo una suposición educada.

una dirección IP se representa tradicionalmente como cuatro bytes, es decir, xxx.xxx.xxx.xxx, pero en realidad es un largo sin signo. Por lo tanto, debe convertir la representación 192.168.1.1 a un int sin escribir. podrías convertirlo así.

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

Probablemente haya una mejor manera, pero esto funciona:

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

Para obtener una forma más completa de manejar IP (v6, material de estilo CIDR, etc.), consulte cómo se hace en py-radix , esp. prefix_pton .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top