Reputation: 361
We have developed a DLL in Delphi 10 that we use in some legacy Delphi 6 applications. The new functionality in the DLL is only for a few clients and is therefore not required to roll out to all our clients. If we try to deploy the Delphi 6 application without the DLL we get the error "The code execution cannot proceed because xxx.dll was not found.". We get the error the moment the app starts to run. Is there a way to prevent this error if the DLL does not exist? In our Delphi 6 code we already use FileExists(xxx.dll) to see if we should make the functionality in the DLL available therefore we don't have the risk that the application will crash if the dll is not present.
We would also be keen to learn where/when the Delphi 6 app checks if the DLL exists because it happens before the Application.Initialize, which is the first line of code in the DPR file.
Upvotes: 3
Views: 1962
Reputation: 31393
This type of failure is caused by statically (aka : implicitly) linking the DLL. There is no option if you have chosen to use static linking - the DLL must be present on the system trying to run the application.
There are two ways to allow the DLL to be optionally present.
One is to rewrite the affected sections of code to use dynamic linking (aka : explicit ) for your DLLs instead of static linking. For Delphi 6, this is unfortunately your only option.
The other, an option if you are targeting Windows only and if you are compiling with Delphi 2010 or greater, is to use delayed loading by decorating your import declarations with the delayed
directive:
function GetSomething: Integer; external 'somelibrary.dll' delayed;
This is really just syntactic sugar resting on top of what is otherwise dynamic loading, but it does provide an easier path to migrate statically linked code to a dynamic linked model without needing an extensive rewrite.
The delayed directive is useful in the case where the imported routines do not exist on the target operating system on which the application is run. Statically imported routines require that the operating system find and load the library when the application is started. If the routine is not found in the loaded library, or the library does not exist, the Operating System halts the execution of the application. Using the delayed directive enables you to check, at run time, whether the Operating System supports the required APIs; only then you can call the imported routines.
Note: Trying to call a delayed routine that cannot be resolved results in a run-time error (or an exception, if the SysUtils unit is loaded).
In either case, delayed or dynamic loading, you would need to catch the failure to resolve the DLL and gracefully deny users access to whatever functions the DLL provides.
Upvotes: 9