Domanda

dato il seguente codice:

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

come posso comprimerlo correttamente per una DLL che lo prevede come un tipo di dati c_ulong?

Ho provato a usare:

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

tuttavia, il metodo c_ulong () restituisce un errore perché necessita di un numero intero.

c'è un modo per usare struct.pack per raggiungere questo obiettivo?

È stato utile?

Soluzione

Inet_aton restituisce una stringa di byte. Questa era la lingua franca per le interfacce in linguaggio C.

Ecco come decomprimere quei byte in un valore più utile.

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

Questo valore decompresso può essere utilizzato con i tipi. La cosa esadecimale è solo per mostrarti che il valore decompresso assomiglia molto a un indirizzo IP.

Altri suggerimenti

Prima un disclaimer: questa è solo un'ipotesi colta.

un indirizzo IP è tradizionalmente rappresentato come quattro byte, ovvero xxx.xxx.xxx.xxx, ma è in realtà un lungo senza segno. Quindi dovresti convertire la rappresentazione 192.168.1.1 in un int non modificato. potresti convertirlo in questo modo.

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

Probabilmente c'è un modo migliore, ma funziona:

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

Per un modo più completo di gestione degli IP (v6, roba in stile CIDR, ecc.) controlla come viene fatto in py-radix , esp. prefix_pton .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top