2010-02-05 3 views
5

Questa è una domanda di Python. Ho una variabile AIn Python, come accedere a un array uint16 [3] avvolto da SWIG (cioè scartare un oggetto PySwigObject)?

>>> A 
<Swig Object of type 'uint16_t *' at 0x8c66fa0> 

>>> help(A) 
class PySwigObject(object) 
    Swig object carries a C/C++ instance pointer 

L'esempio di cui da A è un array contiguo uint16 [3] e il problema è quello di ottenere l'accesso a tale matrice da Python.

In Python, come posso creare una variabile B di lunghezza 3, che mi dà accesso in lettura/scrittura alla stessa memoria puntata dal puntatore avvolto in A?

Credo che il problema ha due parti:

  1. Come ottenere il puntatore di A. (credo 0x8c66fa0 punti a un oggetto Swig, non l'oggetto avvolto).
  2. Come inizializzare una sorta di array Python utilizzando un puntatore di memoria e un tipo di dati noto. (Numpy ha un metodo frombuffer, ma quello che sembra essere necessario è un metodo frommemory.) Forse sarà necessario un casting.

Questo dovrebbe essere facile credo, ma ho letto e hacking per più di un giorno!

Per risolvere la seconda parte, penso che un esempio potrebbe cominciare in questo modo:

>>> import numpy 
>>> C = numpy.ascontiguousarray([5,6,7],"uint16") 
>>> C 
array([5, 6, 7], dtype=uint16) 
>>> C.data 
<read-write buffer for 0x8cd9340, size 6, offset 0 at 0x8902f00> 

Quindi provare a costruire B (di qualsiasi tipo vettoriale) utilizzando "0x8902f00" e "uint16" e verificare se la modifica B [2] provoca cambiamenti in C [2].

Mille grazie per i vostri suggerimenti o un chiaro esempio.

saluti,

Owen

risposta

6

dopo più leggere e roba provare, le risposte sono le seguenti:

 
1. The wrapped pointer in PySwigObject A is available as A.__long__() . 

2. A raw pointer can be cast into an indexable type using ctypes as follows 

import ctypes 
pA = ctypes.cast(A.__long__(), ctypes.POINTER(ctypes.c_uint16)) 

Poi gli elementi possono essere affrontate come pA [0], pA [ 1] ecc

pA punta alla stessa memoria dell'oggetto originale, pertanto fare attenzione a non utilizzare pA dopo aver eliminato l'oggetto originale.

Ecco un esempio per la seconda parte del problema (utilizzando un puntatore non elaborato di tipo noto in Python),

C = numpy.ascontiguousarray([5,6,7],"uint16") # make an array 
C 
rawPointer = C.ctypes.data 
pC = ctypes.cast(rawPointer, ctypes.POINTER(ctypes.c_uint16)) 
pC[0:3] 
pC[1]=100 
pC[0:3] 
C 

Esecuzione esempio in Python mostrerà che sia C [1] e pC [1] è stato modificato in 100.

Risolto. :)

Problemi correlati