DLL i problemy z pluginem

0

No witam, mam problem z pluginem. Wydaje mi się, że wszystko powinno działać ok, jednak tak nie jest. Aplikacja, która korzysta z pluginów to usługa Windows, więc ciężko jest to debugować.

W każdym razie, po krótce kod wygląda tak:

var
  FAppInterface: IAppInterface;
  lHandle: THandle
  ConnectProc: procedure(const AppIFace: IAppInterface; AppConnectionString: PChar);
begin
//TPlugin to obiekt dziedziczący po TInterfacedObject i implementujący konkretny interfejs
//w konstruktorze jest tylko inherited

  FAppInterface:=TPlugin.Create; 
  
//załadowanie biblioteki
  lHandle:=LoadLibrary('plugin.dll'); //poprawna nazwa pliku

//pobranie adresu procedury 
  @ConnectProc:=GetProcAddress(lHandle, 'Connect');
  if @ConnectProc = nil then
  begin
    InvalidPlugin:=true;
  end else
  begin
    ConnectProc(FAppInterface, PChar(AppDBConnectionString));
  end;

//reszta kodu  
end;

Usługa wywala się na ConnectProc. Do dll już nie wchodzi.
Podejrzewam, że to może chodzić o coś z interfejsem albo rzutowaniem na PChar. Ale nie mam pojęcia.
Interfejs jest potrzebny do tego, żeby dll mogło wywoływać różne metody w programie.
Procedura w dllce ma dyrektywę stdcall.

O co tu może chodzić?

0

Nawet nie sprawdzasz, czy LoadLibrary nie zwrocilo bledu.

Lepsza praktyka pisania uslug jest napisanie klasy, ktora spelnia calosc funkcjonalnosci uslugi i testowanie jej uzytej w prostej aplikacji z przyciskami start/pauza/wznow/stop, a potem - jak dziala - przeniesienie do szkieletu uslugi, ktory przeciez robi to samo.

0
Szczawik napisał(a)

Nawet nie sprawdzasz, czy LoadLibrary nie zwrocilo bledu.

Lepsza praktyka pisania uslug jest napisanie klasy, ktora spelnia calosc funkcjonalnosci uslugi i testowanie jej uzytej w prostej aplikacji z przyciskami start/pauza/wznow/stop, a potem - jak dziala - przeniesienie do szkieletu uslugi, ktory przeciez robi to samo.

Generalnie napisałem sobie aplikację testową teraz i podczas wywołania metody z dll dostaję AV.

Ale, czy to nie jest tak, że jeśli mi LoadLibrary zwróci błąd, to nie załaduje biblioteki i wtedy GetProcAddress nie zwróci mi adresu tylko nil?

Nadal nie wiem, co mam robić.

[dopisane]
Sprawdziłem LoadLibrary i zwraca normalnego handla. Nie ma żadnego błędu.
Ale przy wywołaniu procedury mam AV

[dopisane 2]
Właśnie coś rozkminiłem.
Program dllExportViewer pokazuje mi adres procedury taki: 0x0055cb38
Adres relatywny taki: 0x0015cb38
Natomiast funkcja GetProcAddres zwraca mi 152CB38

Czyli ni w ząb ni w oko. Co jest?

[dopisane 3]
Dołożyłem dyrektywę stdcall do deklaracji zmiennej proceduralnej i teraz dzieje się już zupełnie coś dziwnego. Otóż po wykonaniu procedury, debugger wchodzi mi do destruktora klasy odpowiedzialnej właśnie za te dllki. :|

0

OK, rozkminiłem, w którym miejscu jest błąd.

Otóż, po kolei. Chodzi o interfejsy.

Mój interfejs jest zdefiniowany : IAppInterface.
Mam też typ TPlugin dziedziczący po TInterfacedObject i implementujący IAppInterface.

Następnie w aplikacji tworzę obiekt tej klasy:

  //FAppInterface jest typu IAppInterface
  FAppInterface:=TPlugin.Create;

Potem przekazuje go w procedurze dllki:

var
  ConnectProc: procedure(const AppIFace: IAppInterface; AppConnectionString: PChar);
begin
  //ładowanie dll i odnalezienie adresu procedury Connect i wywołanie procki z dll
  ConnectProc(FAppInterface, PChar(AppDBConnectionString));  
end;

A oto fragment kodu z dll:

var
  AppInterface: IAppInterface;
  AppDBConnection: TADOConnection; //adoConnection do bazy programu


//============= Podłączenie ===========================\\
procedure Connect(const AppIFace: IAppInterface; AppConnectionString: PChar); stdcall;
begin
  AppInterface:=AppIFace; //tu się wywala

  //podłączenie do bazy programu
  AppDBConnection:=TADOConnection.Create(nil);
//inny kod
end;

Tylko czemu mi się to wywala? Jakieś różnice pomiędzy IAppInterface, a typem TPlugin? TPlugin nie ma żadnych metod nie zawartych w interfejsie.

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