En Python, cómo acceder a un uint16 [3] array envuelto por SWIG (es decir unwrap un PySwigObject)?

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

  •  18-09-2019
  •  | 
  •  

Pregunta

Esto es cuestión de Python. Tengo una variable A

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

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

La instancia referido por A es una matriz de uint16 contigua [3] y el problema es obtener acceso a la matriz a partir de Python.

En Python, ¿cómo puedo crear una variable B de longitud 3, que me da acceso de lectura / escritura a la misma memoria apuntada por el puntero envuelto en una?

Creo que el problema tiene dos partes:

  
      
  1. ¿Cómo obtener el puntero de A. (creo 0x8c66fa0 puntos a un objeto trago, no el objeto envuelto).
  2.   
  3. ¿Cómo inicializar una especie de matriz Python usando un puntero de memoria y un conocido tipo de datos. (Numpy tiene un método frombuffer, pero lo que parece ser necesario es un método frommemory.) Tal vez será necesario algún casting.
  4.   

Esto debería ser fácil, creo, pero he estado leyendo y la piratería durante más de un día!

Para resolver la segunda parte, creo que un ejemplo podría comenzar de esta manera:

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

A continuación, tratar de construir B (de cualquier tipo vector) usando "0x8902f00" y "uint16" y prueba si el cambio de B [2] causa cambios en C [2].

Muchas gracias por sus sugerencias o un claro ejemplo.

Saludos,

Owen

¿Fue útil?

Solución

Después de más lectura y tratando de materia hacia fuera, las respuestas son las siguientes:

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 ) )

A continuación, los elementos se pueden tratar como pA [0], pA [1] etc

puntos Pa a la misma memoria que el objeto original, por lo tanto, tener cuidado de no utilizar pA después se elimina el objeto original.

Este es un ejemplo para sólo la segunda parte del problema (en el uso de un puntero prima de tipo conocido en 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

Ejecutar el ejemplo en Python mostrará que tanto C [1] y pC [1] han sido cambiados para 100.

resuelto. :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top