Em Python, como para aceder a um uint16 [3] matriz envolvido por SWIG (isto é, um Desprendimento PySwigObject)?

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

  •  18-09-2019
  •  | 
  •  

Pergunta

Esta é a pergunta Python. Eu tenho uma variável A

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

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

O exemplo referido por A é um uint16 matriz contígua [3] e o problema é o de obter acesso a essa matriz a partir do Python.

Em Python, como posso criar uma variável B de comprimento 3, que me dá acesso de leitura / gravação para a mesma memória apontada pelo ponteiro envolto em A?

Eu acho que o problema tem duas partes:

  1. Como obter o ponteiro fora do A. (acho 0x8c66fa0 aponta para um objeto Swig, não o objeto embrulhado).
  2. Como inicializar algum tipo de variedade Python usando um ponteiro de memória e um tipo de dados conhecidos. (Numpy tem um método frombuffer, mas o que parece ser necessário é um método frommemory.) Talvez alguns fundição serão necessários.

Isso deve ser fácil eu acho, mas eu tenho lido e hacking por mais de um dia!

Para resolver a segunda parte, eu acho que um exemplo poderia começar desta maneira:

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

Então tenta compilação B (de qualquer tipo de vector) utilizando "0x8902f00" e "uint16" e testar se alterando B [2] provoca alterações em C [2].

Muito obrigado por suas sugestões ou um exemplo claro.

Saudações,

Owen

Foi útil?

Solução

Depois de mais lendo e tentando coisas fora, as respostas são as seguintes:

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

Em seguida, os elementos podem ser tratadas como pA [0], pA [1], etc

pontos aa para a mesma memória que o objeto original, portanto, tome cuidado para não usar pA depois que o objeto original é apagado.

Aqui está um exemplo para apenas a segunda parte do problema (em usar um ponteiro bruto do tipo conhecido em 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

Executando o exemplo em Python vai mostrar que ambos C [1] e pC [1] foram mudados para 100.

resolvido. :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top