2008-11-25 6 views
3

donné le code suivant:Python: emballage une adresse IP comme ctype.c_ulong() pour une utilisation avec DLL

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

comment puis-je emballer correctement ce pour une DLL qu'il attend en tant que 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 il a besoin d'un nombre entier.

est-il un moyen d'utiliser struct.pack pour accomplir cela?

Répondre

6

Le inet_aton retourne une chaîne d'octets. Cela a été l'lingua franca pour les interfaces en langage C.

Voici comment décompresser ces octets en 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 déballée peut être utilisée avec des types de ctypes. La chose hex est juste pour vous montrer que la valeur déballée ressemble beaucoup à une adresse IP.

0

D'abord un avertissement: Ceci est juste une supposition éclairée.

Une adresse IP est traditionnellement représentée sous la forme de quatre octets, c'est-à-dire xxx.xxx.xxx.xxx, mais elle est en réalité longue non signée. Vous devriez donc convertir la représentation 192.168.1.1 en un entier non-uni. vous pouvez le convertir comme ça.

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

Il y a probablement une meilleure façon, mais cela fonctionne:

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

Pour une façon plus complète de gérer les adresses IP (v6, trucs de style CIDR, etc), regardez comment cela se fait en py-radix, esp. prefix_pton.

Questions connexes