[Delphi] DLL wywołujący procedurę z EXE

0

W pliku DLL chcę wywołać funkcję znajdującą się w pliku EXE:

W DLL'u wygląda to tak:

[...]
var PokazOkno: procedure(i:integer);
begin
 @PokazOkno := GetProcAddress(ExeHandle, 'PokazOkno');
 if Assigned(@PokazOkno) then
   PokazOkno(1)
 else
  MessageBox(0, 'Nie ma tej procedury', '',0);
end;
[...]

Zmienna ExeHandle zawiera uchwyt do formy w EXE (Form1.Handle) przy ładowaniu biblioteki.

W pliku EXE procedura ta wygląda tak:

procedure PokazOkno(i:integer);
begin
 ShowMessage('Jakiś komunikat '+IntToStr(i));
end;

I niestety to mi nie działa. W DLL'u zawsze mam ten komunikat, że 'Nie ma tej procedury'.
Co zrobić, żeby DLL "widział" tę procedurę w pliku EXE?
Próbowałem dopisywać do: procedure PokazOkno(i:integer); stdcall; itp.
ale ciągle jej nie widzi. Może trzeba ją gdzieś dopisać też przed implementation?

Co jest nie tak?

0

Eee, nie da sie tak zrobic. Conajwyzej mozesz przekazac do dll w jakims parametrze wskaznik do procedury.

0

Jasne, że się da. Jeśli DLL będzie posiadał wskaźnik instancji procesu pliku EXE, to może to wywołać tak samo, jak z funkcję z innego DLL. Pewnie zapomniałeś w pliku EXE wyeksportować procedurkę. Poniżej kod - działający, sprawdzony.

Aplikacja główna:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type TB_Proc = procedure();

procedure TForm1.Button1Click(Sender: TObject);
var B:TB_Proc;
    DLL:THandle;
begin
DLL:=LoadLibrary('lib.dll');
if (DLL<>0) then
  begin
  B:=GetProcAddress(DLL, 'B');
  if (@B<>nil) then
    B();
  FreeLibrary(DLL);
  end;
end;

procedure A(i:integer);
begin
ShowMessage(inttostr(i));
end;

exports A;

end.

Kod biblioteki lib.dll

library lib;


uses
  SysUtils, Classes, Windows;

{$R *.res}

type TA_Proc = procedure(i:integer);

procedure B();
var A:TA_Proc;
begin
A:=GetProcAddress(MainInstance, 'A');
if (@A<>nil) then A(20);
end;

exports B;

begin
end.

Warto zwrócić uwagę, że MainInstance zwraca w aplikacji oraz bibliotece instancję aplikacji uruchamiającej, ale HInstance zwraca w aplikacji oraz biblitece ich własną instancję (jest więc różne, w zależności od miejsca sprawdzenia).

1 użytkowników online, w tym zalogowanych: 0, gości: 1