0

I wrote a BPL project and added output .bpi file to another EXE project. The EXE project compiles and links well. The EXE runs well if I put .bpl file in the same folder as .exe file. However, the EXE fails to run if I put .bpl file in other folders than .exe file, and it shows "The program can't start because XXX.bpl is missing...".

I also wrote a DLL version and put .dll file in other folders than .exe file. I added the .dll to the EXE project's "C++ Linker"->"Advanced"->"Delay load DLLs" list, and added SetDllDirectory() function call to my custom search path. The EXE runs well. It seems that .bpl can not work the same as .dll if delay-loaded with custom search path via SetDllDirectory(), am I right?

Test BPL code is like following:

"TestPackage.h"

class PACKAGE TestPackage
{
   TestPackage( void );
   int GetInt( void );
};

"TestPackage.cpp"

#include "TestPackage.h"
#pragma package(smart_init)

TestPackage::TestPackage( void ){}
int TestPackage::GetInt( void ){ return 1000; }

And the test form application code is like following:

"TestApp.cpp"

#include "TestPackage.h"

void __fastcall TForm1::Button1Click( TObject* Sender )
{
   TestPackage* package = new TestPackage;
   int ret = package->GetInt();
   Application->MessageBoxA( IntToStr(ret).c_str(), L"test", 0 );
}

I disabled both "Build with runtime packages" and "Dynamic RTL" in application options. I put TestPackage.bpl in the folder as EXE and the EXE worked well. I could upgraded BPL separately from EXE, say to let TestPackage::GetInt() return other numbers. So the net result seems I can deploy my custom BPL with EXE, and other BPLs, like RTL and VCL, are still statically linked in EXE. The only limitation is that my custom BPL must be in the same folder as EXE, is there any way to overcome this?

odomchen
  • 45
  • 7
  • A BPL **is** a DLL, just with a different file extension. A BPL is loaded into memory the same way a DLL is. The main difference is that a BPL has additional things that are loaded by `LoadPackage()` (which calls `LoadLibrary()` internally). I don't know if the linker can delay-load a BPL, though (I have never tried). You might need to use a [delay-load hook](http://docwiki.embarcadero.com/Libraries/en/SysInit.SetDliNotifyHook2) to handle the `dliNotePreLoadLibrary` event to call `LoadPackage()` instead of `LoadLibrary()`. Otherwise, forget delay-loading and just call `LoadPackage()` directly – Remy Lebeau Apr 21 '16 at 19:53
  • Hi Remy. I found that BPL is implicitly added to EXE project's runtime packages list, and I unchecked "Build with runtime packages" option. Does it mean that the BPL MUST be found in EXE's library search path (PATH or same directory as EXE), otherwise EXE can not run due to BPL missing? In other words, even if I use `LoadPackage()`, the BPL search path is always the same, and I can not specify the full path of BPL to `LoadPackage()`. – odomchen Apr 22 '16 at 03:30
  • if you build *without* runtime packages enabled, the package content will be statically compiled directly into the EXE, no BPL file needed. It is only when runtime packages are enabled that BPL files are linked to and need to be deployed. – Remy Lebeau Apr 22 '16 at 04:12
  • Hi @Remy. I don't want to deploy other BPLs with EXE except my own BPL, such as vcl and rtl, as a result I unchecked "Build with runtime packages". The end users only have one EXE and one (my custom) BPL in different directories (ex. Bin\ and Libs\), and the BPL can be upgraded separately from the EXE. I thought I can achieve this as I do with DLL via delay-loading and `SetDllDirectory()`. – odomchen Apr 22 '16 at 05:42
  • you can't deploy your own BPL and not also deploy the RTL BPLs as well. They go together. By their nature, a BPL links to other BPLs, they are not static. So either you build with runtime packages enabled and deploy a smaller EXE and relevant BPLs, or you build with runtime packages disabled and deploy a larger EXE and no BPLs. – Remy Lebeau Apr 22 '16 at 15:04
  • Hi @Remy. I edited my question. It seems that I could deploy my custom BPL and EXE, while VCL and RTL are still statically linked in EXE. Do I misunderstand anything? – odomchen Apr 23 '16 at 03:28

0 Answers0