Python: compiler une adresse IP en tant que ctype.c_ulong () à utiliser avec une DLL
-
11-07-2019 - |
Question
étant donné le code suivant:
import ctypes
ip="192.168.1.1"
thisdll = ctypes.cdll['aDLL']
thisdll.functionThatExpectsAnIP(ip)
comment puis-je correctement emballer cela pour une DLL qui l'attend comme un type de données c_ulong?
J'ai essayé d'utiliser:
ip_netFrmt = socket.inet_aton(ip)
ip_netFrmt_c = ctypes.c_ulong(ip_netFrmt)
Cependant, la méthode c_ulong ()
renvoie une erreur car elle nécessite un entier.
existe-t-il un moyen d'utiliser struct.pack
pour accomplir cela?
La solution
inet_aton renvoie une chaîne d'octets. Auparavant, c’était la lingua franca pour les interfaces en langage C.
Voici comment décompresser ces octets dans une valeur plus utile.
>>> import socket
>>> packed_n= socket.inet_aton("128.0.0.1")
>>> import struct
>>> struct.unpack( "!L", packed_n )
(2147483649L,)
>>> hex(_[0])
'0x80000001L'
Cette valeur non compressée peut être utilisée avec ctypes. L'hex est simplement pour vous montrer que la valeur décompressée ressemble beaucoup à une adresse IP.
Autres conseils
Tout d'abord, une clause de non-responsabilité: il ne s'agit que d'une supposition éclairée.
une adresse IP est traditionnellement représentée par quatre octets - c'est-à-dire xxx.xxx.xxx.xxx, mais est en réalité un long signe. Vous devez donc convertir la représentation 192.168.1.1 en un entier non chiffré. vous pouvez le convertir comme ça.
ip="192.168.1.1"
ip_long = reduce(lambda x,y:x*256+int(y), ip.split('.'), 0)
Il existe probablement un meilleur moyen, mais cela fonctionne:
>>> ip = "192.168.1.1"
>>> struct.unpack('>I', struct.pack('BBBB', *map(int, ip.split('.'))))[0]
3232235777L
Pour une gestion plus approfondie des adresses IP (v6, CIDR, etc.), consultez la procédure décrite dans py-radix , en particulier prefix_pton .