4
votes

I'm not having any luck importing a Delphi DLL into Inno Setup (Unicode). The DLL has a simple procedure..

procedure Foo(); stdcall;
begin

end;

exports
  Foo;

The DLL is included in the installer source, and added to the files list:

[Files]
Source: "MyDLL.dll"; Flags: dontcopy

Then, I extract this DLL in the initialization:

function InitializeSetup(): Boolean;
begin
  ExtractTemporaryFile('MyDLL.dll');
end;

And finally, declared this procedure in the script:

function DoFoo(): Bool;
  external '[email protected] stdcall';

However, when I run the setup, I get an error:

Cannot Import dll: <utf8>MyDLL.dll.

What am I doing wrong?

2
Would have been nice if Inno Setup gave a more descriptive error message, such as, say, for example, File not found MyDLL.dllJerry Dodge
It is the Pascal Script engine who raises this exception. But yes, Inno Setup side might check if the file exists in the CodeRunnerOnDllImport event method for libraries which are loaded at initialization (not forced to delay load). If the library wouldn't exist, it would report some more sensible message, terminate the setup and avoid attempting to import function from a non existing library file anymore. Yes, such a check would be fine.TLama

2 Answers

12
votes

Since you haven't used delayed loading in your function import, Inno Setup loader failed to run because it didn't found your library. That's because checks whether function exports are available are performed before the InitializeSetup event is fired and so your library was not yet extracted from the archive.

In your case is adding delayload import option the right way. But you can omit manual extracting and tell the installer to extract the library for you if you add files: prefix before the library file name. This prefix is documented as:

During Setup, a special 'files:' prefix may also be used to instruct Setup to automatically extract one or more DLLs from the [Files] section before loading the first DLL.

The whole import in your case can be then shortened to:

[Files]
Source: "MyDLL.dll"; Flags: dontcopy

[Code]
procedure Foo;
  external 'Foo@files:MyDLL.dll stdcall delayload';
4
votes

I found the solution right after posting this question by using delayload on the import...

function DoFoo(): Bool;
  external '[email protected] stdcall delayload';