En utilisant ctypes python pour obtenir un tampon de flotteurs de bibliothèque partagée en chaîne de python

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

Question

Je suis en train d'utiliser ctypes python pour utiliser ces deux fonctions C à partir d'une bibliothèque partagée:

bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()

La première fonction fonctionne bien. Je peux dire en plaçant un code de débogage dans la bibliothèque partagée et vérifier l'entrée.

Le problème est d'obtenir les données sur. Le tampon RVB est un pointeur sur un flotteur (évidemment) et ce pointeur reste constant pendant toute la durée de l'application. Par conséquent, chaque fois que je veux décomprimer une image, je l'appelle decompress_rgb et alors besoin de voir ce qui est à l'endroit pointé par getRgbBuffer. Je sais que la taille de la mémoire tampon est (720 * 288 * sizeof (float)) donc je suppose que cela doit entrer en jeu quelque part.

Il n'y a pas de type c_float_p Je pensais donc essayer ceci:

getRgbBuffer.restype = c_char_p

Alors je fais:

ptr = getRgbBuffer()
print "ptr is ", ptr

qui produit juste:

ptr = 3078746120

Je suppose que l'adresse est réelle plutôt que le contenu, mais même si je déréférencement avec succès le pointeur et obtenir le contenu, ce serait seulement le premier caractère.

Comment puis-je obtenir le contenu de l'ensemble du tampon dans une chaîne de python?

Modifier Nous avons dû changer:

getRgbBuffer.restype = c_char_p

à

getRgbBuffer.restype = c_void_p

mais la réponse de BastardSaint travaillé.

Était-ce utile?

La solution

Pas complètement testé, mais je pense qu'il est quelque chose le long de cette ligne:

buffer_size = 720 * 288 * ctypes.sizeof(ctypes.c_float)
rgb_buffer = ctypes.create_string_buffer(buffer_size) 
ctypes.memmove(rgb_buffer, getRgbBuffer(), buffer_size)

est la fonction ctypes.memmove(). De ctypes documentation :

  

memmove(dst, src, count)   Identique à la fonction de la bibliothèque standard C memmove: copies count octets du src à dst. dst et src doivent être entiers ou ctypes instances qui peuvent être convertis en pointeurs.

Après l'extrait ci-dessus est exécuté, rgb_buffer.value retournera le contenu jusqu'à la première '\0'. Pour obtenir tous les octets sous forme de chaîne de python, vous pouvez couper la chose. buffer_contents = rgb_buffer[:]

Autres conseils

Il a été un moment que j'utilisé ctypes et je n'ai pas quelque chose qui retourne un « double * » assez pratique pour tester cela, mais si vous voulez un c_float_p:

c_float_p = ctypes.POINTER(ctypes.c_float)

La réponse de lecture BastardSaint, vous voulez juste les données brutes, mais je ne sais pas si vous faites cela comme une solution de contournement pour ne pas avoir c_float_p.

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