[英]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.