1
votes

I need your help, please. I'm trying to call function from DLL written in Delphi 10 Seattle from Inno Setup (ANSI). But I do not understand what is the problem. If I make application in Delphi and call this function from DLL, it works perfectly! See code listing:

Delphi DLL:

function Process(Pb: TProgressBar): Integer; stdcall;
var
  I: integer;
begin
  for I := 0 to 1000 do
  begin
    Pb.Position := I;
    Pb.Update;
    Sleep(10);
  end;
end;

Exports
  Process;

Inno Setup (ANSI):

function Count(Progr: TNewProgressBar): integer; external 'Process@files:CallC.dll stdcall delayload';

procedure NewButton1Click(Sender: TObject);
begin
   Count(NewProgressBar1);
end;

After call I get Access Violation. But, comment in dpr file i read, ShareMem write first line, but zero effect.

Show me how to correctly update progress bar in Inno Setup from Delphi DLL, please.

1
I don't think you can expect to pass an object like a progress bar between the installer and the dll. You'll need to do the access to the prog bar in the installer.David Heffernan
Also, you say that you can call the DLL fine from a Delphi host. But even that is wrong. If it works it's by luck rather than design.David Heffernan
Ammm... how me doing this?Malcolm
You'll need to callback the installer to advance the PB.David Heffernan
Of course, but how? Maybe You show me Simple Example code?Malcolm

1 Answers

1
votes

You cannot call object methods this way. You may be lucky to get this working, if you use exactly the same version of Delphi as the one Inno Setup is built with, as your tests with Delphi application shows. But it is still wrong and unreliable, do not do it. As you use a different Delphi version, the layout of the progress bar class in memory is different, hence the "Access violation".


For this particular task, you can easily do with just a handle to the progress bar:

function Process(Handle: THandle): Integer; 
var
 I: Integer;
begin
  SendMessage(Handle, PBM_SETRANGE, 0, 1000 shl 16);
  for I := 0 to 1000 do
  begin
    SendMessage(Handle, PBM_SETPOS, I, 0);   
    UpdateWindow(Handle);
    Sleep(10);
  end;
end;

In Inno Setup, call the function like:

function Count(Handle: THandle): integer;
  external 'Process@files:CallC.dll stdcall delayload';

procedure NewButton1Click(Sender: TObject);
begin
  Count(NewProgressBar1.Handle);
end;

For more advanced tasks, you need to use a callback.

See