Article

From:
To:
Don Wilcox
Subject:
Re: Another problem using Synchronize in a DLL [Edit]
Newsgroup:
embarcadero.public.cppbuilder.rtl

Re: Another problem using Synchronize in a DLL [Edit]

<Don Wilcox> wrote in message news:✉forums.embarcadero.com...

> I am encountering a problem with using Synchronize
> to update the UI.

Starting in BCB6, when TThread::Synchronize() was re-written to support 
Linux, TThread::Synchronize() stopped working inside of a DLL natively and 
now requires extra work on the DLL's and main Application's parts in order 
to function correctly.  A DLL is a self-contained module, thus the DLL and 
main Application has separate copies of the internal queue used by 
TThread::Synchronize(), and those copies are are not shared with each other. 
When the main Application processing pending TThread::Synchronize() 
requests, it can only see the requests that are made by its own threads.  It 
cannot see the requests that are made by the DLL's threads.

This design change introduced in BCB 6 also affects the TThread::Notify() method added in later BCB versions as well.
In order to process the DLL requests, you will have to export an extra function from your DLL that calls the DLL's copy of the CheckSynchronize() function, and then have your main Application call that new DLL function periodically, eg:
{code:cpp} bool __export CheckSync() {     return CheckSynchronize(); } {code}
{code:cpp} // a TTimer::OnTimer event handler void __fastcall TForm1::SyncTimerElapsed(TObject *Sender) {     CheckSync(); } {code}
> What I have is a thread that is instantiated in a DLL:

Your DLL code is quite dangerous in general.  You are passing VCL object 
pointers across the DLL boundary.  That can only safely work if the 
Application and DLL are compiled with the exact same RTL and VCL versions. 
As soon as you start mixing versions, you are asking for a lot of trouble. 
A better design is to have the main Application pass the TListView's HWND to 
the DLL instead of the TListView pointer itself (and have the DLL return the 
TThread's ID or Handle instead of the TThread pointer itself, or better 
nothing about the Thread at all).  In fact, doing it this way, you do not 
need to use Synchronize() at all.  You can use SendMessage() instead, and 
let the OS handle the synchronizing for you, eg:

{code:cpp} #include <vcl.h> #pragma hdrstop
#include <Classes.hpp>
#pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) {     return 1; }
class LVThread : public TThread { public:     LVThread(HWND alv) : TThread(false), lv(alv), l(0) { }
protected:     void __fastcall Execute()     {         while (!Terminated)         {             Sleep(1000);
            LV_ITEM item = {0};             item.mask = LVIF_IMAGE | LVIF_GROUPID;             item.iItem := ListView_GetItemCount(lv);             item.iImage = -1;             item.iGroupId = -1;
            if( ListView_InsertItem(lv, &item) > -1 )                 ListView_SetItemText(lv, item.iItem, 0, String("Line " + IntToStr(l++)).c_str());         }     }
private:     HWND lv;     int l; };
LVThread *Thread = NULL;
bool __export Start(HWND lv) {     if( Thread == NULL )         Thread = new LVThread(lv);     return true; }
bool __export Stop() {     if( Thread != NULL )     {         Thread->Terminate();         Thread->WaitFor();         delete Thread;         Thread = NULL;     }     return true; } {code}
Otherwise, in order to share VCL object pointers across the DLL boundary safely, both the main Application and the DLL have to be compiled with Runtime Packages enabled, or else the DLL has to be changed into a Package itself.
> When I run the application, the items only show up when I move the mouse
> to keep the message pump going.

I am surprised if that works at all, since the main Application does not 
have access to the DLL's synchronize queue.

-- Remy Lebeau (TeamB)
FYI: Phrase searches are enclosed in either single or double quotes
 
 
Originally created by
Tamarack Associates
Thu, 28 Mar 2024 18:41:59 UTC
Copyright © 2009-2024
HREF Tools Corp.