2017-09-28 3 views
1

J'ai une DLL qui définit une structure. Dans cette structure est un champ qui a le type CRITICAL_SECTION, comme inclus de windows.h. Comment puis-je définir une structure ctypes dans python pour référencer ce type? Puisque CRITICAL_SECTION est lui-même une structure (avec des références à d'autres structures dans sa propre définition), dois-je vraiment définir les équivalents python ctype de telle sorte que j'ai un python CRITICAL_SECTION que je peux référencer? Y a-t-il un meilleur moyen?Définir la structure python ctypes avec un type de champ inconnu

Exemple de programme C:

... 
typedef struct some_struct { 
    ... 
    CRITICAL_SECTION field1; 
} SOME_STRUCT; 
... 

Exemple de programme Python:

... 
class SOME_STRUCT(Structure): 
    _fields_ = [... ('field1', CRITICAL_SECTION)] 

Comment puis-je faire ctypes reconnaître ce que CRITICAL_SECTION est sans aller dans le trou de lapin de définir tout jusqu'à types primitifs que ctypes reconnaît?

+0

Untested, mais aux fins de Python, définissant comme 'c_ubyte * x' où x est' sizeof (CRITICAL_SECTION) 'pourrait être suffisant. Tant que votre structure finale a la bonne taille, vous pouvez la traiter comme un tableau opaque d'octets. –

+0

alors quel est le 'sizeof (CRITICAL_SECTION)' de toute façon: D –

+0

@ AnttiHaapala demander à votre compilateur C: ^) Sur le mien, il était de 40 octets, mais il pourrait varier. Je suis venu avec une meilleure réponse ci-dessous. –

Répondre

1

Il vous suffit d'obtenir la bonne taille de la structure. InitializeCriticalSection devrait gérer la mise en place de la structure.

regardant dans les en-têtes Windows, cela devrait fonctionner sur les systèmes 32 et 64 bits:

from ctypes import * 
from ctypes import wintypes as w 

# Set to an unsigned int type that is 32- or 64-bit depending on OS architecture. 
# I didn't see a wintype that worked. 
ULONG_PTR = c_size_t 

class CRITICAL_SECTION(Structure): 
    _fields_ = [('DebugInfo',w.LPVOID), 
       ('LockCount',w.LONG), 
       ('RecursionCount',w.LONG), 
       ('OwningThread',w.HANDLE), 
       ('LockSemaphore',w.HANDLE), 
       ('SpinCount',ULONG_PTR)] 

k32 = WinDLL('kernel32') 
InitializeCriticalSection = k32.InitializeCriticalSection 
InitializeCriticalSection.argtypes = POINTER(CRITICAL_SECTION), 
InitializeCriticalSection.restype = None 

s = CRITICAL_SECTION() 
InitializeCriticalSection(byref(s)) 
+0

Merci pour la réponse. Cela semble fonctionner pour moi mais j'ai encore besoin de temps pour vraiment le tester. Je vais revenir et accepter ce que je sais que cela fonctionne à 100% avec mon application particulière. – zephyr