Pointeurs et tableaux en ctypes Python

j'ai une DLL contenant une fonction C avec un prototype comme ceci:

int c_read_block(uint32 addr, uint32 *buf, uint32 num);

je veux l'appeler de Python en utilisant des ctypes. La fonction attend un pointeur vers un morceau de mémoire, dans lequel elle écrira les résultats. Je ne sais pas comment construire et transmettre un tel morceau de mémoire. La documentation sur les ctypes n'est pas très utile.

construisant un tableau et le passant "byref", comme ceci:

    cresult = (c_ulong * num)()
    err = self.c_read_block(addr, byref(cresult), num)

Donne cette erreur message:

ArgumentError: argument 3: <type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of pointer to c_ulong_Array_2

je suppose que c'est parce que le tableau ulong de Python n'est rien comme un tableau cuint32. Dois-je utiliser create_char_string. Si oui, comment convaincre Python de" lancer " ce tampon dans un LP_c_ulong?

33
demandé sur Andrew Bainbridge 2009-09-01 19:38:20

3 réponses

Vous pouvez lancer avec l' cast fonction :)

>>> import ctypes
>>> x = (ctypes.c_ulong*5)()
>>> x
<__main__.c_ulong_Array_5 object at 0x00C2DB20>
>>> ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong))
<__main__.LP_c_ulong object at 0x0119FD00>
>>> 
49
répondu Mark Rushakoff 2009-09-01 16:10:10

Vous pouvez lancer le résultat, mais ctypes vous permet d'utiliser un tableau à la place d'un pointeur, directement. Le problème est le byref dans votre code (ce qui serait l'équivalent d'un pointeur vers un pointeur):

Donc au lieu de:

cresult = (c_ulong * num)()
err = self.c_read_block(addr, byref(cresult), num)

essaie:

cresult = (c_ulong * num)()
err = self.c_read_block(addr, cresult, num)
0
répondu ephemer 2018-08-24 12:31:00
POINTER(list of ulong)

In [33]: ptr = ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong*5))
In [34]: ptr
Out[34]: <__main__.LP_c_ulong_Array_5 at 0x23e2560>
-1
répondu bemehow 2016-04-25 17:41:09