在python中使用ctypes与仅包含函数指针的c结构进行交互
问题描述:
我在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?
感谢您的任何帮助。
答
ctypes文档说你可以从一个地址创建一个ctypes.PYFUNCTYPE。
如果你在你的结构中获得了函数的地址,那么你可以用ctypes.PYFUNCTYPE作为Python函数包装它,然后把它作为一个常规的ctype函数调用。
我没有测试它自己,但我认为这也许东西在你的情况
探索参见http://docs.python.org/library/ctypes.html#ctypes.PYFUNCTYPE
我希望它能帮助
答
像这样的东西应该是一个很好的起点(我没有你的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或测试,给我你的结果,我可以帮助更多的,如果你仍然有问题。