2016-05-24 5 views
0

Das ist etwas, mit dem ich schon eine ganze Weile herumgestanden habe, also würde jeder Input geschätzt werden.Warum stimmt ctypes.addressof() nicht mit id() für ctypes.Structure-Objekte überein?

Lauf Python 2.7 (CPython) ist Folgendes beachten ctypes.Structure eine SCSI generic IO-Struktur darstellt:

import ctypes 
class SGIOHeader(ctypes.Structure): 
    _fields_ = [ 
     ('interface_id', ctypes.c_int), 
     ('dxfer_direction', ctypes.c_int), 
     ('cmd_len', ctypes.c_ubyte), 
     ('mx_sb_len', ctypes.c_ubyte), 
     ('iovec_count', ctypes.c_ushort), 
     ('dxfer_len', ctypes.c_uint), 
     ('dxferp', ctypes.c_void_p), 
     ('cmdp', ctypes.c_void_p), 
     ('sbp', ctypes.c_void_p), 
     ('timeout', ctypes.c_uint), 
     ('flags', ctypes.c_uint), 
     ('pack_id', ctypes.c_int), 
     ('usr_ptr', ctypes.c_void_p), 
     ('status', ctypes.c_ubyte), 
     ('masked_status', ctypes.c_ubyte), 
     ('msg_status', ctypes.c_ubyte), 
     ('sb_len_wr', ctypes.c_ubyte), 
     ('host_status', ctypes.c_ushort), 
     ('driver_status', ctypes.c_ushort), 
     ('resid', ctypes.c_int), 
     ('duration', ctypes.c_uint), 
     ('info', ctypes.c_uint)] 

Wenn ich ein Objekt unter Verwendung der obigen Klasse instanziiert, neige ich dazu, das zu beobachten, was durch zurückgegeben ctypes.addressof() ist nicht annähernd, was durch den Aufruf von id() auf dem Objekt zurückgegeben:

>>> sgio = SGIOHeader() 
>>> hex(id(sgio)) 
'0x10eb5ed40' 
>>> hex(ctypes.addressof(sgio)) 
'0x7fdeca700130' 

ich verstehe, dass es ein Delta zwischen id sein sollte() und ctypes.addressof(), um die Metadaten entsprechen notwendig für Referenzzählung und Objektidentifikation auf. Was ich nicht verstehe ist, warum die Python-Adresse des Objekts so weit von der Speicheradresse der Backing-Struktur entfernt ist?

Der Grund, dass dies ein Problem ist, ist, weil, wenn ich versuchen würde, eine ioctl mit dem ctypes.addressof() -Wert ausgeben, ich immer ein EFAULT bekommen, weil das Objekt als außerhalb des Adressraums meines Prozesses gilt. Wenn das Objekt im Heap lebt, wie kann seine Backing-Adresse so weit von seiner Identität entfernt sein? Was verstehe ich falsch, wenn es darum geht, wie Python-Objekte im Speicher abgelegt werden? Gibt es unterschiedliche Adressierungsschemata (es scheint, dass ich entweder einen 32-Bit- oder einen 64-Bit-Wert bekomme)?

+1

Werfen Sie einen Blick hier: http://stackoverflow.com/questions/23600052/what-is-the-difference-between-idobj-and-ctypes-addressofobj-in-cpython –

+0

Nur für das Protokoll, ich war eigentlich in den klassischen ctypes "wenn Sie nicht die Art der Funktion Argumente angeben, werden sie standardmäßig auf 32-Bit-Ganzzahlen Problem" ... scheint albern aber oh gut. –

Antwort

0

Da die C-Struktur modelliert und das Python-Objekt, das für es Proxies ist, zwei separate Konzepte sind.

id() gibt Ihnen die Speicheradresse des Python-Proxy-Objekts, ctypes.addressof() gibt Ihnen die Adresse der tatsächlichen C-Struktur. Sie können das Python-Objekt nicht an anderen C-Code übergeben, aber Sie können die C-Struktur an anderen C-Code übergeben.

Verwandte Themen