J'accède à une bibliothèque partagée C++ à partir de Python. La bibliothèque partagée C++ gère un analyseur de signal et est distribuée sans la source.Python & CTypes Erreur de pointeur nul
L'une des fonctions nécessite la transmission d'une struct dans l'appel de fonction et je ne suis pas sûr de le faire correctement en utilisant ctypes.
La définition du struct dans le fichier d'en-tête est:
typedef struct saIQPacket {
float *iqData;
int iqCount;
int purge;
int dataRemaining;
int sampleLoss;
int sec;
int milli;
} saIQPacket;
Et la fonction que je finis par appeler:
SA_API saStatus saGetIQData(int device, saIQPacket *pkt);
En python, j'ai créé une classe comme suit:
class IQPacketData (ct.Structure):
_fields_ = [('iqData',ct.c_float*48611),
('iqCount',ct.c_int),
('purge', ct.c_int),
('dataRemaining', ct.c_int),
('sampleLoss', ct.c_int),
('sec', ct.c_int),
('milli', ct.c_int)]
J'utilise ensuite ce qui précède comme suit:
self.iqPurge = ct.c_int(0)
self.iqDataRemaining = ct.c_int(0)
self.iqSampleLoss = ct.c_int(0)
self.secondsRemaining = ct.c_int(0)
self.millisecondsRemaining = ct.c_int(0)
self.iqarraySize = ct.c_int(24305)
self.iqArr = (ct.c_float*48611)()
self.saIQPacketData = IQPacketData(self.iqArr,
self.iqarraySize,
self.iqPurge,
self.iqDataRemaining,
self.iqSampleLoss,
self.secondsRemaining,
self.millisecondsRemaining)
Après l'initialisation du dispositif, j'appeler la fonction comme suit:
err = self.dll.saGetIQData(self.deviceHandle,ct.pointer(self.saIQPacketData))
Lorsque la fonction est exécuté, il renvoie une valeur de -1 qui se traduit par une erreur de pointeur nul. Y a-t-il quelque chose qui ne va pas dans la façon dont je construis la structure et que je la passe dans l'appel de fonction?
'iqData' est censé être un' 'char *, pas un tableau. Changez-le en 'ct.POINTER (ct.c_float)'. Vous pouvez toujours affecter un tableau au champ. ctypes est assez intelligent pour vérifier que le type d'élément de tableau est correct et stocke l'adresse dans le champ struct tout en gardant une référence au tableau sous-jacent dans les _objects de la structure. – eryksun
Il n'est pas nécessaire d'envelopper manuellement les valeurs entières en tant qu'instances 'c_int'. De plus, l'appel peut utiliser 'ct.byref (self.saIQPacketData)' au lieu d'allouer un pointeur. – eryksun
Merci @eryksun. changer le type d'iqData et passer un pointeur au constructeur a corrigé le problème. – wgebers