2010-10-04 117 views
1

我在dll中只有包含函数指针(即vtable)的结构,我想在python中进行交互(用于测试目的)。我在使用ctypes的时候遇到了一些麻烦。在python中使用ctypes与仅包含函数指针的c结构进行交互

我所拥有的是:

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?

感谢您的任何帮助。

回答

1

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

如果你在你的结构中获得了函数的地址,那么你可以用ctypes.PYFUNCTYPE作为Python函数包装它,然后把它作为一个常规的ctype函数调用。

我没有测试它自己,但我认为这也许东西在你的情况

探索参见http://docs.python.org/library/ctypes.html#ctypes.PYFUNCTYPE

我希望它能帮助

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或测试,给我你的结果,我可以帮助更多的,如果你仍然有问题。