В Python, как получить доступ к массиву uint16[3], обернутому SWIG (т.е.развернуть PySwigObject)?

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

  •  18-09-2019
  •  | 
  •  

Вопрос

Это вопрос 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. 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.

Решаемая.:)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top