Obtention de l’adresse du type de données personnalisé en C à partir de Python à l’aide de ctypes

J’ai une structure vector en C avec les champs suivants,

 struct vector { unsigned char* data; unsigned long size; unsigned long elemsize; unsigned long capacity; }; 

et il existe quelques fonctions qui agissent en conséquence sur les instances de vector , telles que:

 struct vector* vector_new(unsigned long elemsize); void vector_delete(struct vector* vec); void vector_push_back(struct vector* vec, void* value, unsigned long elemsize); void vector_reserve(struct vector* vec, unsigned long cap); ... 

et ainsi de suite (imitant un style c ++ std::vector ).

Dans d’autres sections de ma base de code, j’ai des structures de composants, par exemple mirror :

 struct mirror { double R; double T; // extra fields omitted - see mirror_wrapper.py below struct vector* input[2]; // [vector*, vector*] struct vector* output[2]; // [vector*, vector*] }; 

qui, entre autres, a les méthodes suivantes,

 struct mirror* mirror_alloc(); int mirror_init(double R, double T, struct mirror* mrr); // ibn is the "initial-beam-number" void mirror_set_left_input(struct vector** input, unsigned long ibn, struct mirror* mrr); void mirror_set_right_input(struct vector** input, unsigned long ibn, struct mirror* mrr); 

où l’on passe l’adresse du champ de output d’un autre composant à ces méthodes set_input pour les “connecter”.

Les champs d’ input et de output de chaque composant stockent toujours des instances de struct beam – un type de données qui stocke simplement un champ double complex et un champ double .


Actuellement, je suis en train de construire des wrappers en Python (3.5) pour appeler les différentes méthodes dans un environnement orienté object à utiliser ultérieurement pour faciliter le traçage, etc. utiliser ctypes pour construire une bibliothèque partagée du code C.

Ce qui suit sont les emballages que j’ai jusqu’à présent,

vector_wrapper.py

 from ctypes import cdll from ctypes import Structure from ctypes import c_ubyte from ctypes import c_ulong from ctypes import POINTER class Vector(structure): _fields_ = [ ("data", POINTER(c_ubyte)), ("size", c_ulong), ("elemsize", c_ulong), ("capacity", c_ulong)] 

mirror_wrapper.py

 from ctypes import cdll from ctypes import Structure from ctypes import byref from ctypes import c_double from ctypes import c_ubyte from ctypes import c_ulong from ctypes import c_bool from ctypes import POINTER from ctypes import pointer from vector_wrapper import Vector lib = cdll.LoadLibrary('./ctn_lib.so') class Mirror(Structure): _fields_ = [ ("R", c_double), ("T", c_double), ("pR", c_double), ("pT", c_double), ("tuning", c_double), ("mass", POINTER(c_double)), ("last_time", c_double), ("net_force", c_double), ("dfcoeff", c_double), ("phfcoeff", c_double*2), #phfcoeff is a double complex in c code ("rpfcoeff", c_double), ("input", POINTER(Vector)*2), ("output", POINTER(Vector)*2), ("has_left_input", c_bool), ("has_right_input", c_bool)] 

Existe-t-il un moyen quelconque d’obtenir l’adresse d’un champ de output d’un composant (par exemple un mirror ), qui a le type struct vector** , et de le transmettre, par exemple, à une fonction Mirror.set_left_input tant que paramètre d’ input ?

De plus, je suppose qu’il est nécessaire de créer tous les champs dans les _fields_ d’une structure python correspondant aux champs dans les structures C – il est donc possible d’omettre certains champs de ce descripteur ou pas.

    Existe-t-il un moyen quelconque d’obtenir l’adresse d’un champ de sortie d’un composant (par exemple un miroir), qui a le type vecteur struct **, et de le transmettre, par exemple, à une fonction Mirror.set_left_input en tant que paramètre d’entrée?

    Pour accéder au composant de sortie d’un miroir en fonction de vos structures:

     >>> m = Mirror() >>> m.output[0] <__main__.LP_Vector object at 0x00000199607CA0C8> 

    Pour le transmettre à une fonction par référence:

     >>> mirror_set_left_input(byref(m.output[0]),...) 

    De plus, je suppose qu’il est nécessaire de créer tous les champs dans les champs d’une structure python correspondant aux champs dans les structures C – c.-à-d. Est-il possible d’omettre certains champs de ce descripteur ou non?

    Non, vous ne pouvez pas omettre de champs de votre définition de structure, sinon la présentation binary de la structure C sous-jacente ne sera pas correcte.