2017-12-07 2 views
0

zurückgibt Ich habe eine DLL, die eine Klasse enthält, die eine Schnittstelle implementiert. Die DLL hat eine exportierte Methode, die die Schnittstelle zurückgibt.Zugriffsverletzung, die Bibliothek freigibt, die eine Schnittstelle für eine Klasse innerhalb der DLL

Ich kann die DLL erfolgreich explizit laden, aber wenn ich versuche, Free Library zu verwenden, erhalte ich Zugriffsverletzung. Ich habe den impliziten Link nicht verwendet, weil ich den expliziten Modus verwenden muss.

Wenn ich nur die Bibliothek laden und gleich danach frei, ohne die Schnittstelle, alles funktioniert gut.

Dll

library Tef; 

uses 
    uTTefFacade; 

{$R *.res} 

exports 
    CreateTef; 

begin 
end. 

Schnittstelle in dll:

type 
    ITefFacade = interface 
    ['{77691DD1-C6E9-4F75-951F-BFA1468DC36C}'] 
    function IniciarTransacao(AParam: TTefIniciarTransacaoParamDTO): TTefIniciarTransacaoResultDTO; 
    end; 

Klasse in dll:

type 
     TTefFacade = class (TInterfacedObject, ITefFacade) 
     private  
     function IniciarTransacao(AParam: TTefIniciarTransacaoParamDTO): TTefIniciarTransacaoResultDTO; 
     public 
     constructor Create; 
     destructor Free; 
     end; 

function CreateTef: ITefFacade; export; stdcall; 

function CreateTef: ITefFacade; 
begin 
    Result := ITefFacade(TTefFacade.Create); 
end; 

Exe:

procedure TForm1.FormCreate(Sender: TObject); 
var 
    CreateTef: function: ITefFacade; stdcall; 
begin 
    try 
    FTef := nil; 

    FHTef := LoadLibrary('Tef.dll'); 
    if (FHTef > 0) then 
    begin 
     @CreateTef := GetProcAddress(FHTef, 'CreateTef'); 
     if (@CreateTef <> nil) then 
     FTef := CreateTef; 
    end; 

    if (FTef = nil) then 
     ShowMessage('Error.'); 
    except 
    on E: Exception do 
     ShowMessage('Erro: ' + E.Message); 
    end; 
end; 

Und hier in der anrufenden Free Library, tritt Zugriffsverletzung auf.

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    FreeLibrary(FHTef); 
end; 
+2

Setzen Sie Ihre Referenz des FTef irgendwo auf Null vor dem Entladen? Wenn das nicht der Grund sein könnte. – Fritzw

+0

Es hat funktioniert, danke! Ich habe FreeAndNil schon einmal ausprobiert und es hat nicht geklappt. Ich dachte nicht, dass ich nur Nil zuweisen soll. – Samuel

+3

Ich denke, es ist Zeit, mehr über die Unterschiede zwischen Klassen und Schnittstellen zu lernen, FreeAndNil auf einer Schnittstelle ist ein nogo – Fritzw

Antwort

4

Sie müssen nil die FTef Referenz vor dem DLL freigegeben wird.

Das Objekt hinter der Schnittstelle lebt in der DLL, Sie sollten dies beachten. Wenn Sie versuchen, das DLL zu entladen, ohne die Schnittstelle zuerst freizugeben, wird es Probleme geben, wenn auf das Objekt nach dem Entladen zugegriffen wird (wie wenn Delphi die Referenz automatisch aufhebt, wenn es den Gültigkeitsbereich verlässt).

Verwandte Themen