Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DLL mit einem Objekt und darin enthaltener Objectlist (https://www.delphipraxis.net/115121-dll-mit-einem-objekt-und-darin-enthaltener-objectlist.html)

Cyberaxx 6. Jun 2008 08:14


DLL mit einem Objekt und darin enthaltener Objectlist
 
Hallo,

Habe ein Programm geschrieben mit sehr vielen Formularen, da ich die Formulare ab und an ändern muß nervt es immer wieder alle User aus dem Programm zu schmeissen nur damit man die Exe Updaten kann, zudem ist die Exe schon 10MB groß.

Ich dachte ich baue es dann zu einem Modularen System um. Habe es mir wohl etwas leichter vorgestellt und stehe natürlich vor einem Problem. Ich lade beim Starten des Programmes Benutzer, Kunden, Artikel jeweils vor über ein Objekt in eine Objectlist.

Delphi-Quellcode:
type
  TArtikel = class(TObject)
  private
    FArtikel: Integer;
    FKey: Integer;
    FName: String;
    FFirma: Integer;
    FMandant: Integer;
    FName2: String;
    FHersteller: String;
    FLagerort: String;
    FGebinde: String;
    procedure SetKey(const Value: Integer);
    procedure SetName(const Value: String);
    procedure SetArtikel(const Value: Integer);
    procedure SetFirma(const Value: Integer);
    procedure SetMandant(const Value: Integer);
    procedure SetName2(const Value: String);
    procedure SetHersteller(const Value: String);
    procedure SetLagerort(const Value: String);
    procedure SetGebinde(const Value: String);
  public
    property Artikel: Integer read FArtikel write SetArtikel;
    property Name: String read FName write SetName;
    property Name2: String read FName2 write SetName2;
    property Firma: Integer read FFirma write SetFirma;
    property Mandant: Integer read FMandant write SetMandant;
    property Hersteller: String read FHersteller write SetHersteller;
    property Lagerort: String read FLagerort write SetLagerort;
    property Gebinde: String read FGebinde write SetGebinde;
    property Key: Integer read FKey write SetKey;
  end;

type
  TWWArtikel = class(TObject)
  private
    FList: TObjectList;
    function GetArtikel(Index: Integer): TArtikel;
  public
    constructor Create(Conn: TZConnection);
    destructor Destroy; override;
    function Count: Integer;
    property Artikel[Index: Integer]: TArtikel read GetArtikel;
    function FindArtikel(ArtikelNr: Integer; var Index: Integer): Boolean;
  end;

...

function TWWArtikel.GetArtikel(Index: Integer): TArtikel;
begin
  Result := (FList.Items[Index]) as TArtikel;
end;
Ich nutze FastMM und übergebe eine Instanz TWWArtikel an die DLL, Das übergeben ansicht funktioniert auch ich kann z.B. auf den Count zugreifen aber sobald ich versuche einen Eintrag aus der Liste zu holen gibt es eine Exception "Ungültige Typenumwandlung"
Gibt es eine Möglichkeit das ich das Überhaupt so nutzen kann in DLLs oder hat es doch eher wenig Sinn?

Definition
Delphi-Quellcode:
type
  TPluginType = (ptDevelop, ptFinal, ptTesting);

type
  TPluginInfo = record
    Name: PChar;
    Author: PChar;
    SDescription: PChar;
    PluginType: TPluginType;
  end;

type
  TPluginGetInfo       = function: TPluginInfo; stdcall;
  TPluginMenuCaption   = function: PChar; stdcall;
  TPluginNumMainOptions = function: Integer; stdcall;
  TPluginNumOptions    = function: Integer; stdcall;
  TPluginGetOption     = function(N: Integer): PChar; stdcall;
  //TPluginExecute       = procedure(Datum: TDate; Customers: TPCustomers; DBUsers: TPDBUsers; WWArtikel: TPWWArtikel); stdcall;
  TPluginExecute       = procedure(Datum: TDate; Customers: TCustomers; DBUsers: TDBUsers; WWArtikel: TWWArtikel); stdcall;
  TPluginInit          = function(FW_Data: TZConnection; Unix: TZConnection;
                            PTV: TZConnection): boolean; stdcall;
Ausführen des Moduls
Delphi-Quellcode:
procedure TPluginManager.ClickEvent(Sender: TObject);
  var
    Index: Integer;
    Lib: Thandle;
    APlugin: TPlugin;

    APluginExecute: TPluginExecute;
    APluginInit: TPluginInit;
begin
  Index := (Sender as TCustomAdvPanel).Tag;

  APlugin := (Self.Plugin(Index));

  if not FileExists(Self.FPluginDir + APlugin.Filename) then begin
    Self.FErrorEventForm.SetErrorEX(Self, 'Frachtverwaltung - Modulmanager', 'Modul ist nicht mehr vorhanden');
    Exit;
    end;

  Lib := LoadLibrary(PChar(Self.FPluginDir + APlugin.Filename));

  if Lib = 0 then begin
    Self.FErrorEventForm.SetErrorEX(Self, 'Frachtverwaltung - Modulmanager', 'Modul konnte nicht geladen werden');
    Exit;
    end;

  @APluginInit := GetProcAddress(Lib, 'Init');
  @APluginExecute := GetProcAddress(Lib, 'Execute');

  if (@APluginInit = nil) or (@APluginExecute = nil) then begin
    Self.FErrorEventForm.SetErrorEX(Self, 'Frachtverwaltung - Modulmanager', 'Moduladressen wurden nicht gefunden');
    Exit;
    end;

  if not APluginInit(Self.FFW_Data, Self.FUnix, Self.FPTV) then begin
    Self.FErrorEventForm.SetErrorEX(Self, 'Frachtverwaltung - Modulmanager', 'Initialisierung des Moduls nicht möglich');
    Exit;
    end;

  try
    APluginExecute(Self.FDatum, FCustomers, FDBUsers, FWWArtikel);
  except
    Self.FErrorEventForm.SetErrorEX(Self, 'Frachtverwaltung - Modulmanager', 'Beim starten des moduls trat ein Fehler auf');
  end;

  FreeLibrary(Lib);
end;
Execute in der DLL
Delphi-Quellcode:
procedure Execute(Datum: TDate; Customers: TCustomers; DBUsers: TDBUsers; WWArtikel: TWWArtikel); stdcall;
begin
  ShowMessage(Customers.Customer[10].KdNr);
  FDatum := Datum;

  try
    Frachtauftraege_Frm := TFrachtauftraege_Frm.Create(Frachtauftraege_Frm);
    Frachtauftraege_Frm.ZQry.Connection := FFW_Data;
    Frachtauftraege_Frm.ZQuery2.Connection := FFW_Data;
    Frachtauftraege_Frm.ZQuery3.Connection := FFW_Data;

    Frachtauftraege_Frm.Anzeigen(FDatum, FCustomers);
  except
    Frachtauftraege_Frm.Free;
  end;
end;
Gerade das Laden der Artikel im vorraus erspart mir natürlich so einiges an Arbeit in den einzelnen Formularen und vorallem Zeit, da ich nicht sändig die Datenbank durchsuchen muss.

Vielleicht kann mir hier jemand bei meinem Problem helfen :)

Gruß

Cyberaxx

Bernhard Geyer 6. Jun 2008 08:39

Re: DLL mit einem Objekt und darin enthaltener Objectlist
 
Ohne verwendung von gemeinsame Runtimepackages (BPL's) darfst du eigentlich keine Objekte zwischen DLL und Exe austauschen, denn Exe.TObject <> Dll.TObject (2 vorhandene unabhängige RTTI-Informationen).

Cyberaxx 6. Jun 2008 08:57

Re: DLL mit einem Objekt und darin enthaltener Objectlist
 
Das bedeutet dann auch ich kann meine Connection zur Datenbank auch nicht übergeben?

Das wären dann mindestens 2 Datenbankverbindungen pro User...

Dann wirds wirklich ohne Bpls nicht gehen, shade eigentlich

Bernhard Geyer 6. Jun 2008 09:09

Re: DLL mit einem Objekt und darin enthaltener Objectlist
 
Geht schon, jedoch ist es aufwändig alles C-Kompatible zu gestalten.

Cyberaxx 6. Jun 2008 09:14

Re: DLL mit einem Objekt und darin enthaltener Objectlist
 
Dan gib mir bitte mal Infos dazu,die Artikel kann ich dann im entsprechenden Modul laden aber die Connection würde ich mindestens schon gerne direkt übergeben.
Zudem wollte ich mit den DLLs ja auch das austauschen der Exe verhindern was ich ja nicht unbedingt bei einem Package weg fällt.

Damit ich jetzt erstmal weiterarbeiten kann werd ich wohl jedes Modul mit einer DConnection ausstatten und dann die Daten der Datebank übergeben, was ich persönlich noch schlimmer finde ;)

shmia 6. Jun 2008 10:56

Re: DLL mit einem Objekt und darin enthaltener Objectlist
 
http://www.obsof.com/delphi_tips/DL613.html


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:52 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