2010-10-04 119 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或測試,給我你的結果,我可以幫助更多的,如果你仍然有問題。