在python中使用ctypes与仅包含函数指针的c结构进行交互

时间:2010-10-04 10:35:18

标签: python ctypes

我在dll中有一个结构,它只包含我想在python中进行交互的函数指针(即vtable)(用于测试目的)。我在使用ctypes解决这个问题时遇到了一些麻烦。

我拥有的是:

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); 

'真实'测试对象将根据需要填充结构。这会被编译成DLL(test.dll)。我想,在python中,能够调用工厂方法来获取指向我的Test结构的指针,然后调用结构中包含的函数指针,但我似乎无法理解它是怎么回事会使用ctypes。有没有人有任何关于做类似事情的指针/例子,或者我应该使用像SWIG或Boost这样的东西?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

这样的事情应该是一个很好的起点(我没有编译你的DLL来测试)

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)

在此之后,您需要调用make_Test()来获取结构,并尝试调用函数。也许用这样的代码:

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

提供dll或测试并告诉我你的结果,如果你还有问题,我可以提供更多帮助。

答案 1 :(得分:1)

ctypes文档说你可以从一个地址创建一个ctypes.PYFUNCTYPE。

如果获得结构中函数的地址,那么可以将它包装为Python函数,这要归功于ctypes.PYFUNCTYPE,然后将其称为常规ctype函数。

我自己没有测试过,但我觉得在你的情况下可能需要探讨

请参阅http://docs.python.org/library/ctypes.html#ctypes.PYFUNCTYPE

我希望它有所帮助