En Python, comment accéder à un réseau uint16 [3] enveloppé par SWIG (à savoir un dépliage PySwigObject)?

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

  •  18-09-2019
  •  | 
  •  

Question

est question Python. J'ai une variable A

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

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

L'exemple visé par A est un uint16 de réseau contigu [3] et le problème est d'obtenir l'accès à ce réseau de python.

En Python, comment puis-je créer une variable B de longueur 3, qui me donne un accès en lecture / écriture à la même mémoire pointée par le pointeur enveloppé dans A?

Je pense que le problème comporte deux parties:

  
      
  1. Comment obtenir le pointeur sur A. (je pense que les points 0x8c66fa0 à un objet Swig, et non l'objet enveloppé).
  2.   
  3. Comment initialiser une sorte de tableau Python à l'aide d'un pointeur de mémoire et un type de données connu. (Numpy a une méthode frombuffer, mais ce qui semble être nécessaire est une méthode frommemory.) Peut-être une coulée sera nécessaire.
  4.   

Cela devrait être facile, je pense, mais je l'ai lu et le piratage depuis plus d'un jour!

Pour résoudre la deuxième partie, je pense qu'un exemple pourrait commencer ainsi:

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

Ensuite, essayez de construire B (quel que soit le type de vecteur) en utilisant "0x8902f00" et "uint16" et le test en cas de changement B [2] provoque des changements dans C [2].

Merci pour vos suggestions ou un exemple clair.

Cordialement,

Owen

Était-ce utile?

La solution

Après plus de lecture et d'essayer des choses dehors, les réponses sont les suivantes:

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

Ensuite, les éléments peuvent être traités comme pA [0], pA [1] etc

Points pA à la même mémoire que l'objet original, donc attention à ne pas utiliser pA après que l'objet initial est supprimé.

Voici un exemple pour la deuxième partie du problème (à l'aide d'un pointeur brut de type connu 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

L'exécution de l'exemple en Python montrera que les deux C [1] et pC [1] ont été modifiés pour 100.

Résolu. :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top