Python: упаковка IP-адреса в виде ctype.c_ulong () для использования с DLL
-
11-07-2019 - |
Вопрос
учитывая следующий код:
import ctypes
ip="192.168.1.1"
thisdll = ctypes.cdll['aDLL']
thisdll.functionThatExpectsAnIP(ip)
как я могу правильно упаковать это для DLL, которая ожидает его как тип данных c_ulong?
Я пытался использовать:
ip_netFrmt = socket.inet_aton(ip)
ip_netFrmt_c = ctypes.c_ulong(ip_netFrmt)
однако метод c_ulong ()
возвращает ошибку, потому что ему нужно целое число. Р>
есть ли способ использовать struct.pack
для этого? Р>
Решение
Inet_aton возвращает строку байтов. Раньше это был лингва-франка для интерфейсов языка Си.
Вот как распаковать эти байты в более полезное значение.
>>> import socket
>>> packed_n= socket.inet_aton("128.0.0.1")
>>> import struct
>>> struct.unpack( "!L", packed_n )
(2147483649L,)
>>> hex(_[0])
'0x80000001L'
Это распакованное значение можно использовать с ctypes. Суть в том, чтобы показать вам, что распакованное значение очень похоже на IP-адрес.
Другие советы
Во-первых, отказ от ответственности: это только обоснованное предположение.
ip-адрес традиционно представлен четырьмя байтами - то есть xxx.xxx.xxx.xxx, но на самом деле это длинный без знака. Таким образом, вы должны преобразовать представление 192.168.1.1 в неподписанный тип int. Вы можете преобразовать это так.
ip="192.168.1.1"
ip_long = reduce(lambda x,y:x*256+int(y), ip.split('.'), 0)
Возможно, есть лучший способ, но это работает:
>>> ip = "192.168.1.1"
>>> struct.unpack('>I', struct.pack('BBBB', *map(int, ip.split('.'))))[0]
3232235777L
Более подробный способ обработки IP-адресов (версия 6, материал в стиле CIDR и т. д.) можно узнать в py-radix , esp. prefix_pton .