tags:

views:

41

answers:

2

Hi,

I have a struct in a dll that only contains function pointers (ie a vtable) that I would like to interact with in python (for test purposes). I am having a bit of trouble working out how to do this using ctypes.

What I have is:

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 'real' Test object will fill in the struct as appropriate. This gets compiled into a DLL (test.dll). I'd like, in python, to be able to call the factory method to get back a pointer to my Test struct and then call the function pointers contained in the struct, but I just can't seem to get my head around how it would work using ctypes. Does anyone have any pointers / examples of doing something similar or should I be using something like SWIG or Boost?

Thanks for any help.

+1  A: 

The ctypes documentation says that you can create a ctypes.PYFUNCTYPE from an address.

If you get the address of the functions in your structure then you can wrap it as a Python function thanks to ctypes.PYFUNCTYPE and then call it as a regular ctype function.

I didn't test it myself but I think it maybe something to explore in your case

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

I hope it helps

luc
A: 

Something like this should be a good starting point (I don't have your DLL compiled to test)

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)

After this, you'll need to call make_Test() to get the struct, and try calling the functions. Perhaps with code like this:

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

Provide the dll or test and give me your results and I can help more if you still have problems.

lunixbochs