2010-10-04 7 views
1

J'ai une structure dans une DLL qui contient uniquement des pointeurs de fonction (ie un vtable) avec lesquels j'aimerais interagir avec python (à des fins de test). J'ai un peu de mal à savoir comment faire cela en utilisant ctypes.Interagir avec un struct struct contenant uniquement des pointeurs de fonction utilisant ctypes en python

Ce que j'est:

struct ITest 
{ 
    virtual char const *__cdecl GetName() = 0; 
    virtual void __cdecl SetName(char const *name) = 0; 
}; 

/* Factory function to create 'real' Test object */ 
extern "C" __declspec(dllexport) struct ITest * CALLCONV make_Test(char const * name); 

A 'réel' objet de test remplira le struct selon le cas. Cela est compilé dans une DLL (test.dll). Je voudrais, en python, pouvoir appeler la méthode factory pour récupérer un pointeur sur ma structure de test, puis appeler les pointeurs de fonction contenus dans la structure, mais je n'arrive pas à comprendre comment fonctionnerait en utilisant ctypes. Est-ce que quelqu'un a des indicateurs/exemples de faire quelque chose de similaire ou devrais-je utiliser quelque chose comme SWIG ou Boost?

Merci pour toute aide.

Répondre

1

La documentation de ctypes indique que vous pouvez créer un ctypes.PYFUNCTYPE à partir d'une adresse.

Si vous obtenez l'adresse des fonctions dans votre structure, alors vous pouvez l'envelopper comme une fonction Python grâce à ctypes.PYFUNCTYPE et ensuite l'appeler comme une fonction ctype régulière.

Je n'ai pas testé moi-même mais je pense qu'il peut-être quelque chose à explorer dans votre cas

Voir http://docs.python.org/library/ctypes.html#ctypes.PYFUNCTYPE

J'espère que cela aide

3

Quelque chose comme cela devrait être un bon point de départ (Je n'ai pas votre DLL compilé pour tester)

from ctypes import Structure, CFUNCTYPE, POINTER, c_char_p, windll 
class ITest(Structure): 
    _fields_ = [ 
      ('GetName', CFUNCTYPE(c_char_p)), 
      ('SetName', CFUNCTYPE(None, c_char_p) 
     ] 

test = windll.LoadLibrary('test.dll') 
test.make_Test.restype = POINTER(ITest) 

Après cela, vous aurez besoin d'appeler make_Test() pour obtenir le struct, et essayer appel les fonctions. Peut-être avec le code comme ceci:

itest = test.make_Test().contents 
itest.SetName('asdf') 
print itest.GetName() 

Fournir la dll ou un test et me donner vos résultats et je peux aider plus si vous avez encore des problèmes.