2

While taking an existing monolithic C++Builder VCL application and splitting it into an exe + DLLs, I'm running into problems with TApplication.

The DLL projects and the exe project have the following options enabled, so they should all share the memory manager and VCL libraries:

  • Link with Dynamic RTL
  • Link with the Delphi Runtime Library
  • Link with runtime packages

From what I understand, these options are needed for issues like memory allocations and VCL component operations to work across DLL boundaries.

Things are mostly working. However, the global TApplication instance is apparently initialized from within one of the DLLs, not from within the exe, with several unwanted results:

  • System::IsLibrary is incorrectly set to true.
  • Application->Icon is not set.
  • Application->Handle is not set.
  • Because Application->Handle is not set, various other problems arise: shortcut keys don't work, there are problems with thread synchronization, etc.

I can work around these problems by setting Application->Icon->Handle and calling Application->CreateHandle from WinMain, but I'm not sure that this is the right solution (especially since the docs say "do not call CreateHandle").

What's the right way to split a C++Builder VCL app into DLLs while sharing VCL components?

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246

2 Answers2

3

You should create your own Runtime Packages instead of plain DLLs. A Package is a special type of DLL that has built-in RTL/VCL support.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you. This sort of works, but it doesn't seem to play well with C++ code. Templates in packages aren't visible outside the package, member constant definitions are rejected by the compiler even though they're required by the standard, inline functions are weird, source filenames with extra dots in them can't be found by the linker, cross-platform C++ files have to be marked up as Delphi-compatible units... Unless there are easy solutions to all of these, these problems seem worse than the ones I started with. – Josh Kelley May 01 '13 at 19:41
  • @JoshKelley: I haven't used packages with C++ much, but I have experimented, and I didn't see many of those issues. They're just a special sort of DLL. Inline: well, you'd expect a DLL to have trouble too. Member constants... odd... can you give an example? Delphi-compatible units, what do you mean, with a declspec? What's I'd suggest is asking a separate question about these problems, or maybe a question about each individual problem. Packages are definitely officially supported by C++ Builder so you're likely to have more luck there than something that is known to have problems (DLLs.) – David May 02 '13 at 07:38
  • 1
    To continue: TApplication isn't the only thing you'll have trouble with using DLLs - the whole Delphi type system and all classes descending from it will have the same issue, since each DLL will have its own copy. Packages are essential for your requirement "while sharing VCL components.". – David May 02 '13 at 07:39
  • @DavidM - Unless I'm missing something, using runtime packages and the dynamic RTL avoids the "each DLL having its own copy" issue, since they all share the same dynamically loaded copy. I'll try and put together a follow-up question with more details on the issues I'm seeing with packages, although I'm starting to run out of time to spend on these issues. – Josh Kelley May 02 '13 at 12:50
  • @JoshKelley Yes, that's that I meant. Sorry if it wasn't clear. It's the main reason to use packages. – David May 02 '13 at 13:33
  • @DavidM - Sorry, I meant that DLLs (instead of packages) can avoid the "each DLL has its own copy" issue as long as the DLLs and exe are built with the "link with dynamic RTL" and "link with runtime packages" options enabled. – Josh Kelley May 02 '13 at 14:06
-1

We resolved issues by using Delay load Dlls (it can be found in exe project c++ linker properties).

More info here: Delay Loading DLLs

Jakub
  • 1