[英]Invoke callback into VB6 from native C DLL
我正在嘗試獲取本機C函數來調用VB6應用程序中的回調。 在VB中,代碼如下所示:
Private Declare Sub StartUp Lib "library.dll" (ByVal cbAddress As Long)
Public Sub MySub
Call StartUp(AddressOf MyCallback)
End Sub
Public Sub MyCallback(ByVal str As String)
' Use str in UI
End Sub
當我從VB6 IDE運行此程序時,一切正常:調用回調,並且可以使用str
參數沒有問題。 但是,當我將VB6應用程序編譯為exe時,調用回調時該應用程序將崩潰。 從我在谷歌搜索中可以看出,這似乎是某種線程問題。 有人建議使用Win32 SendMessage
避免這種線程問題。 我不太清楚該怎么做。 我會在回調中調用SendMessage
嗎? 我如何在主線程上收到此消息? 另外,如何將字符串傳遞給SendMessage?
編輯:我剛剛發現: Vb6應用程序可以在IDE中工作,但可執行文件崩潰
但是,我最初的問題仍然存在。
Edit2:我也應該包括在C代碼中。 這是定義和調用回調的方式:
typedef void (__stdcall *FUNCPTR)(BSTR);
int wslen = MultiByteToWideChar(CP_ACP, 0, cstr, strlen(cstr), 0, 0);
BSTR bstr = SysAllocStringLen(0, wslen);
MultiByteToWideChar(CP_ACP, 0, cstr, strlen(cstr), bstr, wslen);
((FUNCPTR) _cbAddress)(bstr);
SysFreeString(bstr);
同樣,當從IDE調用時,這很好用...
顯然,最理想的選擇是確保回調始終在VB應用程序的主線程上發生。 否則,您將不得不對應用程序中的窗口使用SendMessage()
來利用Window自身在Windows之間的編組能力。
以前,我編寫了一個VB應用程序,該應用程序從DLL進行了回調,該DLL用於與遠程控件集成。 但是DLL使用了另一個線程來與硬件集成。 在我的回調中,我使用帶有WM_COPYDATA
SendMessage()
將數據編組到主VB線程,該線程由子類化代碼拾取。
當然,由於您正在編寫C DLL,而您只是在傳遞回ASCII文本,因此您可以跳過幾個步驟,而不必編寫回調過程或具有子類代碼。 只需使用SetWindowText() API調用將文本直接寫到TextBox
。 確保在始終加載的表單上使用Visible
= False
創建此TextBox
。 然后,您只需要使用以下代碼:
BOOL WINAPI SetWindowText(
_In_ HWND hWnd,
_In_opt_ LPCTSTR lpString
);
HWND m_hWndTextBox
void StartUp(HWND hWndTextBox)
{
m_hWndTextBox = hWndTextBox;
// other stuff
}
void Callback(char *cstr) {
SetWindowText(m_hWndTextBox, cstr);
}
和VB代碼:
' Form "Form1" with text box "Text1".
Private Declare Sub StartUp Lib "library.dll" (ByVal hWndTextBox As Long)
Public Sub MySub
Call StartUp(Text1.hWnd)
End Sub
Private Sub Text1_Change()
DoStuffWithDLLUpdateString Text1.Text
End Sub
而且,您甚至不必將字符串轉換為BSTR-VB會為您執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.