Em Python, como para aceder a um uint16 [3] matriz envolvido por SWIG (isto é, um Desprendimento PySwigObject)?
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:
- Como obter o ponteiro fora do A. (acho 0x8c66fa0 aponta para um objeto Swig, não o objeto embrulhado).
- 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
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. :)