Pergunta

dado o seguinte código:

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

como posso corretamente embalar isso para uma DLL que espera que ele como um c_ulong tipo de dados?

Eu tentei usar:

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

No entanto, o método c_ulong() retorna um erro porque ele precisa de um inteiro.

Existe uma maneira de usar struct.pack para alcançar este objetivo?

Foi útil?

Solução

O inet_aton retorna uma seqüência de bytes. Isto costumava ser o língua franca para interfaces de língua C.

Veja como descompactar os bytes em um valor mais ú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 descompactado pode ser usado com ctypes. A coisa hex é apenas para mostrar que o valor descompactado se parece muito com um endereço IP.

Outras dicas

Primeiro um aviso:. Este é apenas um palpite

um ip-address é tradicionalmente representado como quatro bytes - ou seja XXX.XXX.XXX.XXX, mas é realmente um unsigned long. Portanto, você deve converter a representação de 192.168.1.1 para um int unsiged. você pode convertê-lo assim.

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

Há provavelmente uma maneira melhor, mas isso funciona:

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

Para uma maneira mais completa de lidar com IPs (v6, material de estilo CIDR etc) verificar a forma como ele é feito em py-radix , esp. prefix_pton .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top