Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem mit Variablendeklaration und Vererbung (https://www.delphipraxis.net/210170-problem-mit-variablendeklaration-und-vererbung.html)

slemke76 12. Mär 2022 14:33

Problem mit Variablendeklaration und Vererbung
 
Hallo zusammen,

ich habe ein Problem, bei dem ich nocht nicht einmal weiss, wie ich danach suchen soll :-)

Ich habe eine Anwendung, die dynamisch Import und Export-DLLs nachlädt - es kann jeweils mehrere DLLs je Import/Export geben. Die DLLs implementieren entweder das Interface IImport oder IExport.

Ich habe jetzt einen DLL-Loader für die Import DLLs fertig (funktioniert auch prima):

Delphi-Quellcode:
unit ThreadClasses;

type
  TImportAdapters = array of IImport;

  TPDFThread = class(TThread)
    public
      function DLLLoader(Directory, Filemask: string):TImportAdapters;
  end;
  [...]

function TPDFThread.DLLLoader(Directory, Filemask: string): TAdapters;
type
  TFNGetImportInterface = function(): IImport; stdcall;
  [...]

var
    GetImportInterface: TFNGetImportInterface;
    ImportAdapters: TImportAdapters;
    [..]

begin
    [...]
        if (not Supports(GetImportInterface, IImport)) then GetImportInterface:=nil;
    [...]
end;
Aufgerufen wird der Loader aus einer abgeleiteten Klasse:
Delphi-Quellcode:
unit ThreadImport;
  [...]
type
  TImportThread = class(TPDFThread)
  [...]

procedure TImportThread.Execute;
begin
    ImportAdapters:=DLLLoader(ExtractFilePath(paramstr(0)), 'Import*.dll');
    [...]
end;
Jetzt würde ich natürlich gerne - um doppelten Code zu vermeiden - den Loader auch für den Export nutzen - klar irgendwie :-)

Die Funktion DLLLoader ist schon in der Vaterklasse, verwendet aber Variablen für den Import (IImport, TFNGetImportInterface, etc.) - auch der Rückgabetyp ist derzeit TImportAdapters.

Die Klassen sehen so aus:

TPDFThread = class(TThread) <--- hier soll der DLL-Loader rein
+ TExportThread = class(TPDFThread) <-- von hier soll der DLL-Loader aufgerufen werden
+ TImportThread = class(TPDFThread) <-- dito


Um meine Frage an einem Beispiel fest zu machen:
Delphi-Quellcode:
function DLLLoader(Directory, Filemask: string):TImportAdapters;
Wie muss ich den Variablentypen deklarieren, damit er beim Aufruf aus der Import-Klasse TImportAdapters und beim Aufruf aus der Export-Klasse TExportAdapters zurückgibt? Gleiches gilt für den eigentlichen Code innerhalb von DLLLoader():

Delphi-Quellcode:
if (not Supports(GetImportInterface, IImport)) then GetImportInterface:=nil;

Ich hoffe, ich habe das Problem verständlich ausgedrückt?

Danke,
Sebastian

slemke76 12. Mär 2022 16:27

AW: Problem mit Variablendeklaration und Vererbung
 
Hallo,

ich glaube, ich bin ein wenig weiter :cyclops: mit Hilfe von Generics:

Delphi-Quellcode:
DLLLoader<IImport>(ExtractFilePath(paramstr(0)), 'Import*.dll');

[...]

function TPDFThread.DLLLoader<T>(Directory, Filemask: string): TArray<T>;
type
  TFNGetImportInterface = function(): IImport; stdcall; //IImport
var
    GetImportInterface: TFNGetImportInterface;
    ImportAdapters: array of IImport;
    [...]

begin
    [...]
        GetImportInterface:=GetProcAddress(libs[j], 'GetInterface');

        // in Array für Rückgabe speichern und Parameter übergeben
        j:=Length(ImportAdapters); inc(j); SetLength(ImportAdapters, j);
        ImportAdapters[j-1]:=GetImportInterface; // über GetInterface wird eine Instanz der enthaltenen Klasse created
        ImportAdapters[j-1].SetParameter(PChar('meinKey'), PChar('meineValue'));
    [...]
Wo ich jetzt hänge: Wie bekomme ich ImportAdapters als result zurück gegeben / gecasted?

Ich habe so etwas hier (https://en.delphipraxis.net/topic/47...e-via-generic/) gefunden, damit wirds irgendwie (?) vielleicht gehen, aber wie :gruebel: ?
Delphi-Quellcode:
  p := GetTypeData(TypeInfo(T));
  Assert(ifHasGuid in p.IntfFlags);
  Supports(Self, p.GUID, Result);
Danke,
Sebastian

slemke76 12. Mär 2022 17:59

AW: Problem mit Variablendeklaration und Vererbung
 
Hallo,

sry für selbst-Replys - aber ich habs hinbekommen (wo ich noch vor Stunden gar keine Ahnung hatte, wie das gehen soll und auch nicht gedacht hätte, dass ich das hinbekomme - sonst hätte ich nicht gefragt).

Die Lösung für den letzten Post war, dass man natürlich die Elemente des TArrays casten muss und nicht das fertige Array (logisch):

Delphi-Quellcode:
DLLLoader<IImport>(ExtractFilePath(paramstr(0)), 'Import*.dll');

[...]

function TPDFThread.DLLLoader<T>(Directory, Filemask: string): TArray<T>;
type
  TFNGetImportInterface = function(): IImport; stdcall; //IImport
var
    GetImportInterface: TFNGetImportInterface;
    ImportAdapters: array of IImport;
    [...]

begin
    [...]
        GetImportInterface:=GetProcAddress(libs[j], 'GetInterface');

        // in Array für Rückgabe speichern und Parameter übergeben
        j:=Length(ImportAdapters); inc(j); SetLength(ImportAdapters, j);
        ImportAdapters[j-1]:=GetImportInterface; // über GetInterface wird eine Instanz der enthaltenen Klasse created
        ImportAdapters[j-1].SetParameter(PChar('meinKey'), PChar('meineValue'));

        cntTemp:=Length(result); SetLength(result, cntTemp+1);
        p := GetTypeData(TypeInfo(T));
        Assert(ifHasGuid in p.IntfFlags);
        Supports(ImportAdapters[j-1], p.GUID, result[cntTemp]);
    [...]
Ich hoffe, es hilft mal jemanden :-)

Grüße!

Uwe Raabe 12. Mär 2022 21:21

AW: Problem mit Variablendeklaration und Vererbung
 
Hast du es schon mal mit
Delphi-Quellcode:
ImportAdapters: TArray<T>;
versucht?
Respektive auch
Delphi-Quellcode:
TFNGetImportInterface = function(): T; stdcall;
?
Ohne compilierbaren Code werden die meisten hier aber auch nur raten können.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz