Python: упаковка IP-адреса в виде ctype.c_ulong () для использования с DLL

StackOverflow https://stackoverflow.com/questions/317531

  •  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 .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top