Python: eine IP-Adresse als ctype.c_ulong Verpackung () zur Verwendung mit DLL
-
11-07-2019 - |
Frage
mit dem folgenden Code:
import ctypes
ip="192.168.1.1"
thisdll = ctypes.cdll['aDLL']
thisdll.functionThatExpectsAnIP(ip)
Wie kann ich das richtig für eine DLL packen, die es als c_ulong Datentyp erwartet?
Ich habe versucht mit:
ip_netFrmt = socket.inet_aton(ip)
ip_netFrmt_c = ctypes.c_ulong(ip_netFrmt)
Allerdings gibt die c_ulong()
Methode einen Fehler, weil es eine ganze Zahl benötigt.
gibt es eine Möglichkeit struct.pack
zu verwenden, um dies zu erreichen?
Lösung
Die INET_ATON gibt eine Zeichenfolge von Bytes. Dies verwendet die lingua franca für C-Sprache-Schnittstellen zu sein.
Hier ist, wie dieser Bytes in einem nützlichen Wert auszuzupacken.
>>> import socket
>>> packed_n= socket.inet_aton("128.0.0.1")
>>> import struct
>>> struct.unpack( "!L", packed_n )
(2147483649L,)
>>> hex(_[0])
'0x80000001L'
Der entpackte Wert kann mit ctypes verwendet werden. Die Hex-Sache ist nur um Ihnen zu zeigen, dass der entpackten Wert viel wie eine IP-Adresse aussieht.
Andere Tipps
Zuerst wird ein Haftungsausschluss. Dies ist nur eine Vermutung
eine IP-Adresse wird traditionell als vier Bytes dargestellt - das heißt xxx.xxx.xxx.xxx, aber es ist wirklich ein unsigned long. So sollten Sie die Darstellung 192.168.1.1 zu einem unsiged int konvertieren. Sie könnte es wie folgt umwandeln.
ip="192.168.1.1"
ip_long = reduce(lambda x,y:x*256+int(y), ip.split('.'), 0)
Es gibt wahrscheinlich einen besseren Weg, aber das funktioniert:
>>> ip = "192.168.1.1"
>>> struct.unpack('>I', struct.pack('BBBB', *map(int, ip.split('.'))))[0]
3232235777L
Für eine gründlichere Weise IPs der Handhabung (v6, CIDR-Stil Sachen usw.) überprüfen, wie es in py-radix , esp. prefix_pton .