Wywoływanie procedury z DLL i pobieranie pakietu danych

0

Witam. Biorąc czysto z kompendium przykład zrobiłem takie coś w stylu pluginów, z listy ładuje dynamicznie bibliotekę i wywołuje funkcje rejestracyjną.

procedure TForm1.LoadPluginDll;
var
  DLL : THandle;
  PluginLibrary : procedure;
  NameLib: String;
  F:TextFile;
begin
AssignFile(F,ExtractFilePath(Application.ExeName) + 'Lib\Plugins.lib');
Reset(F);
while not eof(F) do begin
 ReadLN(F,NameLib);
 if (NameLib <> '') AND (FileExists(ExtractFilePath(Application.ExeName)+'Lib\Plugins\'+NameLib)) then
 begin
  DLL := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'Lib\Plugins\'+NameLib)); // załadowanie pliku
  try
    @PluginLibrary := GetProcAddress(DLL, 'registry');  // pobranie wskaźnika do procedury
    if @PluginLibrary = nil then raise Exception.Create('Błąd w bibliotece: '+NameLib);
    PluginLibrary; // wykonanie procedury
  finally
   // FreeLibrary(DLL);
  end;
 end;
end;
end;

Wywołuje procedurę z bibliotek którą załadował ale mam problem bo nie wiem gdzie i jak odczytać pakiet który wysłała dllka

w dll mam

 RegCompiler = packed record
  Name :String[32];
  CompilerTitle :String[64];
  OptionsTitle :String[64];
 end;
  ComponentInfo        = ^RegCompiler;

procedure registry(RegInfo:ComponentInfo);  stdcall;
begin
 with RegInfo^ do begin
   Name          := 'NASM';
   CompilerTitle := 'Asmbler';
   OptionsTitle  := 'Kompilator Asmbler';
 end;
end;

To taki pierwszy raz z zabawami na dynamicznych bo z statycznymi nie mam problemów.

i to samo z wysyłaniem pakietu danych do biblioteki.

Będę wdzięczny za pomoc lub jakieś inne wskazówki

0

Czy to nie będzie po prostu

    @PluginLibrary := GetProcAddress(DLL, 'registry');  // pobranie wskaźnika do procedury
    if @PluginLibrary = nil then raise Exception.Create('Błąd w bibliotece: '+NameLib);
    PluginLibrary(zmienna typu RegCompiler);

?

0

RegCompiler = packed record
ComponentInfo = ^RegCompiler;

Nie rób tak, bo szybko stracisz rachubę który typ jest wskaźnikiem na który, a i inni nie będą wiedzieć o co chodzi.
Konwencja jest taka, że nazywamy typy od litery T, a wskaźniki na nie od litery P:

type PRegCompiler = ^TRegCompiler;
     TRegCompiler = packed record
        ...
0

Azarien dzięki za radę,
Patryk27 chciałbym żeby tak było :(


Znalazłem takie coś na samym dole jest napisane ale mam problem
http://www.bibisoft.piwko.pl/biblioteki.php

procedure TForm1.LoadPluginDll;
type TDLLProcedure = procedure(Data:TRegCompiler);
var
  DLL : THandle;
  PluginLibrary : TDLLProcedure;
  NameLib: String;
  F:TextFile;
begin
AssignFile(F,ExtractFilePath(Application.ExeName) + 'Lib\Plugins.lib');
Reset(F);
while not eof(F) do begin
 ReadLN(F,NameLib);
 if (NameLib <> '') AND (FileExists(ExtractFilePath(Application.ExeName)+'Lib\Plugins\'+NameLib)) then
 begin
  DLL := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'Lib\Plugins\'+NameLib)); // załadowanie pliku
  try
    @PluginLibrary := GetProcAddress(DLL, 'registry');  // pobranie wskaźnika do procedury
    if @PluginLibrary = nil then raise Exception.Create('Błąd w bibliotece: '+NameLib);
    PluginLibrary(); // wykonanie procedury
  finally
    FreeLibrary(DLL);
  end;
 end;
end;
end;

co bym nie wpisał to nie chce działać

PluginLibrary(TUTAJ);
0

skoro var PluginLibrary : TDLLProcedure;, oraz type TDLLProcedure = procedure(Data:TRegCompiler);, to tak jakby było

procedure PluginLibrary(Data:TRegCompiler);

więc musi być tam parametr odpowiedniego typu.

0

Primo :
Tutaj dajesz stdcall;

procedure registry(RegInfo:ComponentInfo);  stdcall;

A tu już nie :

PluginLibrary : procedure;

Zdecyduj się albo wszędzie albo nigdzie.

Secondo :
Zapomniałeś dać argumenty :

PluginLibrary : procedure;

Daj :

PluginLibrary : procedure(var RegInfo:TRegCompiler);stdcall;

I odwołuj się przez referencje, czyli jeszcze w procedurze w DLL trzeba dać :

procedure registry(var RegInfo:ComponentInfo);  stdcall;

Ten kod je bez wskaźników.Czyli wywal te:

ComponentInfo        = ^RegCompiler;

I odwołuj się bezpośrednio do RegCompiler;

Edit: Jeśli bardzo zależy Ci na wskaźnikach, to tutaj poprawiłem Ci ten pierwszy kod :

type
  TRegCompiler = packed record
  Name :String[32];
  CompilerTitle :String[64];
  OptionsTitle :String[64];
end;
 PRegCompiler    = ^TRegCompiler;

procedure TForm1.LoadPluginDll;
var
  DLL : THandle;
  PluginLibrary : procedure(RegInfo: PRegCompiler );stdcall;
  RegCompiler : TRegCompiler;
  NameLib: String;
  F:TextFile;
begin
AssignFile(F,ExtractFilePath(Application.ExeName) + 'Lib\Plugins.lib');
Reset(F);
while not eof(F) do begin
 ReadLN(F,NameLib);
 if (NameLib <> '') AND (FileExists(ExtractFilePath(Application.ExeName)+'Lib\Plugins\'+NameLib)) then
 begin
  DLL := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'Lib\Plugins\'+NameLib)); // załadowanie pliku
  try
    @PluginLibrary := GetProcAddress(DLL, 'registry');  // pobranie wskaźnika do procedury
    if @PluginLibrary = nil then raise Exception.Create('Błąd w bibliotece: '+NameLib);
    PluginLibrary(@RegCompiler); // wykonanie procedury
  finally
   // FreeLibrary(DLL);
  end;
 end;
end;

No i jeszcze DLL'ka

type
  TRegCompiler = packed record
  Name :String[32];
  CompilerTitle :String[64];
  OptionsTitle :String[64];
end;
 PRegCompiler    = ^TRegCompiler;


procedure registry(RegInfo: PRegCompiler);stdcall;
begin
  with RegInfo^ do begin
   Name          := 'NASM';
   CompilerTitle := 'Asmbler';
   OptionsTitle  := 'Kompilator Asmbler';
 end;

0

Dzięki za pomoc wszystkim widzę że spor błędów porobiłem ;(
Ale może komuś się to przyda jak będzie szukać ;]

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