2010-02-05 13 views
5

Esta es la pregunta de Python. Tengo una variable AEn Python, ¿cómo acceder a una matriz uint16 [3] envuelta por SWIG (es decir, desenvolver un PySwigObject)?

>>> 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 contigua uint16 [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 en A?

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. Cómo inicializar algún tipo de matriz de Python utilizando un puntero de memoria y un tipo de datos conocido. (Numpy tiene un método frombuffer, pero lo que parece ser necesario es un método de memoria). Tal vez se necesite algo de casting.

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 de vector) usando "0x8902f00" y "uint16" y probar si el cambio de B [2] causa cambios en C [2].

Muchas gracias por sus sugerencias o un claro ejemplo.

Saludos,

Owen

Respuesta

6

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 abordar como pA [0], pA [ 1] etc.

pA apunta a la misma memoria que el objeto original, por lo tanto, tenga cuidado de no utilizar pA después de eliminar el objeto original.

Aquí se muestra 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 a 100.

Resuelto. :)

Cuestiones relacionadas