从工作线程调用主线程callback函数

场景:我有一个c + + DLL。 在这个DLL中,我创build了一个工作线程。 在工作线程中,我有一个等待用户通过USB硬件设备input的循环。 只有当USB设备上的用户input符合某些标准时,循环才会结束。 另外,我需要实时反馈USB设备的用户使用反馈,以便在屏幕上显示。 它使用Delphi GUI进行反馈。

当用户使用USB设备时,Windows系统会产生callback函数。 此callback函数被写入相同的C ++ DLL文件,并作为USB设备的初始化函数中的参数传入。

我使用DLL中的全局variables作为标志来确定何时该循环必须退出。

我也从Delphi DLL加载这个C ++ DLL。 Delphi DLL – > C ++ DLL反馈显示来自Delphi的DLL。

基本上,我现在面临的问题是函数ptr,funcptr根本不能被调用。 屏幕上没有实时反馈。 这是Delphi DLL中的一个函数。 这是代码行:

(*(reinterprete_cast<FUNCPTR>(funcPtr)))("this is the feedback msg displayed on Delphi GUI"); 

有没有人有这个解决scheme?

我是一个新手,并感谢任何答案。 谢谢您的帮助。

  //Global variable BOOL flag = TRUE; //A function type in Delphi calling app typedef void (__stdcall *FUNCPTR)(PCHAR); //Functions start here..... DWORD WINAPI ThreadProc(LPVOID lpParameter) { do {} while (flag); } function_1st_CalledFromDelphiDLL(FUNCPTR funcPtr) { Initialize_USBDevice(handleUSBDeviceEvent_callback, funcPtr); } function_2nd_CalledFromDelphiDLL() { DWORD threadID; HANDLE hWorkerThread; hWorkerThread = CreateThread(NULL,0,ThreadProc, 0, 0 , &threadID); if (hWorkerThread!=NULL) { WaitForSingleObject(hWorkerThread, 30000); } } //This is the callback function, called by Windows system when user meddles with the USB device handleUSBDeviceEvent_callback(void *funcPtr) { flag = FALSE; //so loop in ThreadProc can exit //The following code cannot be executed at all. Even when i Try MessageBox( NULL,L"msg",NULL,NULL), the message box doesn't popup too. But, I can write something to a filestream here. (*(reinterprete_cast<FUNCPTR>(funcPtr)))("this is the feedback msg displayed on Delphi GUI"); } 

首先,我不会推荐使用变量在线程之间进行通信。 为了您的目的,使用一个事件。

你的DLL:

 HANDLE _exitNow = NULL; HANDLE _queueLock = NULL; // for part 2 below // call this from your main at start bool DLL_Initialize() { _exitNow = CreateEvent(...); _queueLock = CreateMutex(...); ... initialize your device, add the callback ... } // call this from your main at exit void DLL_Shutdown() { SetEvent(_exitNow); } // your worker thread void DLL_Worker() { // use options so WaitFor...() does not block int result = WaitForSingleObject(_exitNow, ...); if(result indicates _exitNow was fired) { CloseHandle(_exitNow); ... shutdown sequence, unhook your callback, deinit your device ... CloseHandle(_queueLock); } } 

这照顾了init / shutdown / worker位。 而现在这个困难的部分。

首先,你不能操作工作线程中的UI位。 我不记得确切的原因 – 它与主线程拥有的Windows消息队列的所有权有关。 如果您所要做的只是显示应更新的内容,则应该执行以下操作:

  • 声明输出数据的队列。 这可能只是一个循环管理的数组。 无论工作。
  • 宣布一个互斥体来保护它。 如果您的队列已经是线程安全的,则可选。
  • 声明get函数和一个put函数,在访问之前检查互斥锁。
  • 声明一个自定义窗口,即使你可以发布在Windows消息队列中。 (在msdn中检查自定义窗口消息)。 并在你的主窗口中使用get()声明一个处理程序,并更新显示。

假设上面,代码的其余部分变成…(请注意,我有一段时间没有这样做,所以名称和声明可能稍微偏离,但原则是一样的)

你的主要节目:

 // double check how to do this exactly. I haven't done this in a long time. const CUSTOM_WINDOW_EVENT = WINDOWS_CUSTOM_MESSAGE + [SOMETHING]; // check for proper syntax function Form.CustomHandler: Integer; handles CUSTOM_WINDOW_EVENT; var S: String; begin S := GetDataFromDLL(); ... update display based on S ... end; 

你的DLL:

 const CUSTOM_WINDOW_EVENT = WINDOWS_CUSTOM_MESSAGE + [SOMETHING]; TQueue queue; // find a suitable type. std::queue<> works fine // delphi will call this <String-type> DLL_GetStatus() { ... wait on mutex using WaitForSingleObject() ... ... read one entry from queue ... ... release mutex ... ... return it ... } void PutStatus(String statusData) { ... wait on mutex using WaitForSingleObject() ... ... write to queue ... ... release mutex ... ... push the custom message to the windows message queue, use PostMessage() IIRC ... } <whatever> handleUSBDeviceEvent_callback(void *funcPtr) { ... read device, compose status data ... PutStats(statusData); } 

我从记忆中研究了所有这些,所以我确定会出现错误。 无论如何,希望你能得到原则。