In Python, come accedere a un uint16 [3] array avvolto da SWIG (cioè unwrap un PySwigObject)?

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

  •  18-09-2019
  •  | 
  •  

Domanda

Questa è Python domanda. Ho una variabile A

>>> 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 con A è una matrice [3] uint16 contigua ed 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à l'accesso in lettura / scrittura alla stessa memoria puntato dal puntatore avvolto in un?

Credo che il problema ha due parti:

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

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 nel C [2].

Molte grazie per i tuoi suggerimenti o un chiaro esempio.

Saluti,

Owen

È stato utile?

Soluzione

Dopo più la lettura e la 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 affrontati come pA [0], pA [1] ecc

pA punti alla stessa memoria come l'oggetto originale, quindi fare attenzione a non usare pA dopo che l'oggetto originale viene eliminato.

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

L'esecuzione l'esempio in Python mostrerà che sia C [1] e PC [1] sono stati cambiati a 100.

risolto. :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top