В Python как получить доступ к массиву uint16 [3], обернутому SWIG (то есть развернуть PySwigObject)? - PullRequest
6 голосов
/ 05 февраля 2010

Это вопрос Python.У меня есть переменная A

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

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

Экземпляр, на который ссылается A, представляет собой непрерывный массив uint16 [3], и проблема состоит в том, чтобы получить доступ к этому массиву из Python.

В Python какя могу создать переменную B длиной 3, которая дает мне доступ на чтение / запись к той же памяти, на которую указывает указатель, заключенный в A?

Я думаю, что проблема состоит из двух частей:

  1. Как получить указатель из A. (я думаю, что 0x8c66fa0 указывает на объект Swig, а не на обернутый объект).
  2. Как инициализировать некоторый массив Python, используя указатель памяти иизвестный тип данных.(У Numpy есть метод frombuffer, но, похоже, нужен метод frommemory.) Возможно, понадобится какое-то приведение.

Это должно быть легко, я думаю, но я былчтение и взлом более одного дня!

Чтобы решить вторую часть, я думаю, что пример может начаться следующим образом:

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

Затем попробуйте построить B (любого типа вектора)используйте «0x8902f00» и «uint16» и проверьте, не вызывает ли изменение B [2] изменения в C [2].

Большое спасибо за ваши предложения или наглядный пример.

С уважением,

Оуэн

1 Ответ

7 голосов
/ 07 февраля 2010

После прочтения и пробных ответов, ответы таковы:

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

Тогда к элементам можно обращаться как pA [0], pA [1] и т. Д.

pA указывает на ту же память, что и исходный объект, поэтому будьте осторожны, чтобы не использовать pA после удаления исходного объекта.

Вот пример только для второй части проблемы (при использовании необработанного указателя известного типа в 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

Запуск примера в Python покажет, что и C [1], и pC [1] были изменены на 100.

решаемая. :)

...