structures récursives de type python

J’ai développé une DLL pour un pilote en C. J’ai écrit un programme de test en C ++ et la DLL fonctionne bien.

Maintenant, je voudrais interagir avec cette DLL en utilisant Python. J’ai réussi à masquer la plupart des structures C définies par l’utilisateur, mais je dois utiliser des structures C à un moment donné. Je suis plutôt novice en python, alors je peux me tromper.

Mon approche consiste à redéfinir quelques structures en python à l’aide de ctype puis à transmettre la variable à ma DLL. Cependant, dans ces classes, j’ai une liste chaînée personnalisée qui contient les types récursifs suivants:

class EthercatDatagram(Structure): _fields_ = [("header", EthercatDatagramHeader), ("packet_data_length", c_int), ("packet_data", c_char_p), ("work_count", c_ushort), ("next_command", EthercatDatagram)] 

Cela échoue car, dans EthercatDatagram, EthercatDatagram n’étant pas déjà défini, l’parsingur renvoie une erreur.

Comment dois-je représenter cette liste liée en python afin que ma DLL la comprenne correctement?

Vous voudrez certainement déclarer next_command en tant que pointeur. Avoir une structure qui se contient n’est pas possible (dans aucune langue).

Je pense que c’est ce que tu veux:

 class EthercatDatagram(Structure): pass EthercatDatagram._fields_ = [ ("header", EthercatDatagramHeader), ("packet_data_length", c_int), ("packet_data", c_char_p), ("work_count", c_ushort), ("next_command", POINTER(EthercatDatagram))] 

La raison pour laquelle

 EthercatDatagram._fields_.append(("next_command", EthercatDatagram)) 

ne fonctionne pas, c’est que la machine qui crée les objects de description (voir la source de la fonction PyCStructType_setattro ) pour accéder à l’atsortingbut next_command n’est activée que lors de l’affectation de l’atsortingbut _fields_ de la classe. Le simple ajout du nouveau champ à la liste passe complètement inaperçu.

Pour éviter ce piège, utilisez toujours un tuple (et non une liste) comme valeur de l’atsortingbut _fields_ : cela indiquera clairement que vous devez atsortingbuer une nouvelle valeur à l’atsortingbut et ne pas le modifier à la place.

Vous devrez accéder à _fields_ manière statique après l’avoir créé.

 class EthercatDatagram(Structure) _fields_ = [...] EthercatDatagram._fields_.append(("next_command", EthercatDatagram))