If Synchronize() is implemented in FreePascal/Lazarus anything like it is in Delphi, it requires the main UI message loop to process sync requests, and that cannot happen in a DLL without cooperation from the EXE that loads the DLL. A DLL is a self-contained module, it does not share the EXE's instance of the RTL, that is why sync requests from a DLL go unprocessed by default. The solution in Delphi is to export a function from the DLL that calls the RTL's CheckSynchronize() function, and then make the EXE call that exported function periodically. A similar solution is likely required for FreePascal/Lazarus.