2014-01-17 163 views
0

我必須使用MFC的C++ dll,我想從python調用它。 這個DLL包含.h文件從Python調用的C++ dll

LONG CommOpen(BYTE port, LONG baud_rate);

然後我在免費軟件dllexp我的函數被調用看到這個標題?CommOpen @ CFIPcmd @@ QAEJEJ @二進制文件z,所以沒有錯誤報告時我在python做

import ctypes

lib = ctypes.WinDLL('C:\Users\toto\FIProtocol.dll')

prototype = WINFUNCTYPE(c_long, c_byte, c_long)

testPt = ctypes.WINFUNCTYPE (prototype)

testApi = testPt (("[email protected]@@[email protected]", lib))

直到有它似乎工作,但後來我想打電話給在Python中的

Long l= CommOpen(5 ,115200);

C++等價,但我沒有鰭我知道如何繼續。 任何幫助將非常感謝!

回答

3

鑑於該問題提出的信息,解決的辦法是:

import ctypes 

lib = ctypes.CDLL(r'C:\Users\toto\FIProtocol.dll') 
CommOpen = getattr(lib, "[email protected]@@[email protected]") 
CommOpen.argtypes = [c_byte, c_long] 
CommOpen.restype = c_long 

,現在是準備打電話:

l = CommOpen(5 ,115200) 

一些注意事項:

  1. 使用CDLL而不是WinDLL,因爲該函數使用默認的cdecl調用約定。使用getattr可以指定損壞的名稱。
  2. 明確指定argtypesrestype總是值得的。

然而,它蒸發,你有一個更大的問題。以上內容是基於您的函數是非成員函數而編寫的。考慮到​​要求函數是非成員函數或靜態函數,這是一個合理的假設。

然而,當我把你的管理函數名稱爲demanger(例如http://pear.warosu.org/c++filtjs/)似乎功能其實:

public: long __thiscall CFIPcmd::CommOpen(unsigned char,long) 

這是一個C++對象的成員函數。這不能從​​訪問。你需要創建一個普通的C風格的包裝器,或者找到一個不同的互操作方法。

+0

那麼它看起來很不錯,但我得到>>> L = CommOpen(5,115200) 回溯(最近通話最後一個): 文件 「」,1號線,在 WindowsError:異常:訪問衝突寫入0x1D1C5504但爲什麼? –

+0

將問題分解爲兩部分。編寫一個包含具有相同名稱和參數的函數的簡單DLL,並從Python中調用它。讓它調用['MessageBeep'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms680356(v = vs.85).aspx)N次。它的工作原理,你的DLL可能會失敗,因爲它沒有找到關於它運行的環境的一些假設。 – ixe013

+1

查看我的更新。你永遠不能從ctypes中調用該函數。 –

0

根據http://docs.python.org/2/library/ctypes.html#calling-functions「您可以像調用任何其他Python一樣調用這些函數。」我會建議運行一個交互式Python控制檯(如ipython)並自己檢查。

嗯,我剛安裝的Python到VirtualBox的Win32和檢查的例子:

 
>>> from ctypes import * 
>>> f = getattr(cdll.msvcrt, "[email protected]@Z") 
>>> f 
<_FuncPtr object at 0x00B7EDC8> 
>>> f() 
24969248 
>>> _ 

所以,是的,你可以調用這些函數對象像Python環境中其它任何功能。正如文件聲稱:)

同樣_cputws工作:

 
>>> cputws = getattr(cdll.msvcrt, "_cputws") 
>>> r = cputws("Hello, World!\n") 
Hello, World! 
>>> r 
0 
>>> 
+0

正如你所看到的,我的函數只能通過在dll二進制文件中找到的名字來識別:?CommOpen @ CFIPcmd @@ QAEJEJ @ Z其中包含特殊字符。因此,我不能直接在python控制檯中使用lib.functiontocall調用它..必須有其他方法 –

+0

編輯答案並給出更多示例。 – user3159253

+0

>>> f()的 回溯(最近通話最後一個): 文件 「」,1號線,在 ValueError異常:過程大概叫沒有足夠的論據(8個字節丟失) >>> F(5, 115200) 回溯(最近呼叫最後一次): 文件「」,第1行,在 WindowsError:異常:訪問衝突寫入0x1D1C5504謝謝,但我怎樣才能用我想要的參數調用這個API? –