Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Komponente in DLL auzslagern (https://www.delphipraxis.net/93788-komponente-dll-auzslagern.html)

user0 11. Jun 2007 13:03


Komponente in DLL auzslagern
 
Hallo leute,

ich arbeite an einem größeren Softwareprojekt. Ein Formular enthält eine Komponente (TGLMaterialLibrary vom GLScene-Package), dass nicht von der Language-Suite compiliert werden kann. Ich versuche nun diese Komponente auf ein Formular in einer DLL zu kopieren, und diese zur Laufzeit des Programms aus der DLL zu laden.

Hier der Code der DLL:

Hauptprogramm:
Delphi-Quellcode:
library MatLibDll;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  ShareMem,
  SysUtils,
  Classes,
  formular in 'formular.pas' {Form1};

exports
   get_matLib;

{$R *.RES}

var exitProc_save: pointer;

procedure MyExit();
begin
   if Assigned(Form1) then begin
      Form1.Close;
      Form1.Free;
   end;
   ExitProc := exitProc_save;
end;

begin
   exitProc_save := @ExitProc;
   ExitProc := @MyExit;
   Form1 := TForm1.Create(nil);
   Form1.Show;
end.
Formular:
Delphi-Quellcode:
unit formular;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  GLMisc, GLTexture;

type PGLMaterialLibrary = ^TGLMaterialLibrary;

type
  TForm1 = class(TForm)
    MaterialLib: TGLMaterialLibrary;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var   Form1: TForm1;

function get_matLib(): TGLMaterialLibrary; stdcall;

implementation

{$R *.DFM}

function get_matLib(): TGLMaterialLibrary;
begin
   if not Assigned(Form1)   then Form1 := TForm1.Create(nil);
   result := Form1.MaterialLib;
end;

end.
Im eigentlichen Programm wird die DLL Statisch geladen. Die "fehlerhafte" Komponente habe ich im Designer gelöscht, und die Eigenschaft im Code wider hinzugefügt. Bei FormCreate wird dann folgendes gemacht:

Delphi-Quellcode:
self.MaterialLib := get_matLib();
Eigentlich sollte doch jetzt das weitere Programm gar nicht merken, dass die Komponente nicht auf dem Formblatt liegt?
Trotzdem kommt bei einer Zuweisung ("
Delphi-Quellcode:
FF.Material := MaterialLib.Materials.GetLibMaterialByName('MarkedCase').Material;
") eine Fehlermeldung: "Can not assign TGLMaterialLibrary to a TGLMaterialLibrary". Die Assign-methode ist aber im GLScene Package für solche Objekte definiert.

Wo liegt der Fehler? Oder gibt es eine bessere Möglichkeit eine Komponente von einem Formular in eine extra DLL oder Ressource auszulagern?

user0

Bernhard Geyer 11. Jun 2007 13:11

Re: Komponente in DLL auzslagern
 
Verwende Laufzeitpackages. Ansonsten geht das nicht!

QuickAndDirty 11. Jun 2007 16:37

Re: Komponente in DLL auzslagern
 
Die DLL hat eigene RTTI. deshalb kann der "is" operator nicht über DLL Grenzen Hinweg funktionieren.
In Assign von tpersistent nachfahren z.b. Wird aber immer mit dem is Operator verglichen ob das übergebene
Objekt von gleichen Typ oder vom allgemeineren Typ ist.
Ich habe dieses Problem bei meinen Anwendunge so gelöst das ich z.b. bei stringlisten nicht assign sondern
Clear udn addStrings ausführe.

Wenn du den Quellcode hast würde ich ein interface für die Kompenente entwerfen dann sollte es keine Probleme geben.

user0 12. Jun 2007 08:31

Re: Komponente in DLL auzslagern
 
Zitat:

Zitat von Bernhard Geyer
Verwende Laufzeitpackages. Ansonsten geht das nicht!

Meinst du, ich soll GLScene als Laufzeitpackage compilieren? Oder das ganze Formular, dass von der Language suite nicht übersetzt werden kann als neues Package erstellen und zur laufzeit einbinden?

Bernhard Geyer 12. Jun 2007 08:40

Re: Komponente in DLL auzslagern
 
Zitat:

Zitat von user0
Meinst du, ich soll GLScene als Laufzeitpackage compilieren? Oder das ganze Formular, dass von der Language suite nicht übersetzt werden kann als neues Package erstellen und zur laufzeit einbinden?

Deine Exe und die DLL's müssen mit Laufzeitpackages erstellt werden! Ob nun GLScene oder dein Formular als BPL oder als "normale" DLL compilert wird ist dann nicht mehr so relevant. Wichtig ist das beide (Exe und DLL/BPL) die gleichen BPL's laden um sie als gemeinsame Klassenbibliothek verwenden zu können.

user0 13. Jun 2007 09:21

Re: Komponente in DLL auzslagern
 
:coder2: Damit ich das richtig verstehe: Es ist nicht möglich, eine komponente eines Programms in eine externe Datei (DLL / dpk) zu packen und sie zur Laufzeit in das Hauptprogramm zu kopieren, ohne Laufzeitpackages zu verwenden (einzelnes kopieren der Eigenschaften währe zu aufwendig)?

Elvis 13. Jun 2007 09:28

Re: Komponente in DLL auzslagern
 
Zitat:

Zitat von user0
:coder2: Damit ich das richtig verstehe: Es ist nicht möglich, eine komponente eines Programms in eine externe Datei (DLL / dpk) zu packen und sie zur Laufzeit in das Hauptprogramm zu kopieren, ohne Laufzeitpackages zu verwenden?

Suche bitte hier in der DP nach Hier im Forum suchenDLL Objekte, Hier im Forum suchenDLL Packages und Hier im Forum suchenDLL Interfaces.
Das wurde schon seeeehr oft besprochen, falls du dann noch Fragen hast, komm' einfach hierher (diesen Thread) zurück.
Aber lies dir bitte die anderen Threads durch.

user0 13. Jun 2007 12:18

Re: Komponente in DLL auzslagern
 
Sorry. Habe gestern offenbar nicht richtig gesucht.
Die Antwort ist also "Ja, dass geht nicht!". :?

Elvis 13. Jun 2007 14:32

Re: Komponente in DLL auzslagern
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von user0
Sorry. Habe gestern offenbar nicht richtig gesucht.
Die Antwort ist also "Ja, dass geht nicht!". :?

Naja, zumindest nicht direkt.
Du kannst Objekte entweder in flache, exportierte Funktionen verpacken, die den Zeiger auf das Objekt entweder zurückgeben, oder als Parameter kriegen. (So wie die Handles aus der WinAPI)
Oder du benutzt Interfaces, die du in der DLL implementierst, und als Interface in der Echse benutzen kannst.

Ich habe mal ein Archiv mit 2 Projektgruppen angehängt, die das hoffentlich einfach genug illustrieren. :)

user0 15. Jun 2007 08:10

Re: Komponente in DLL auzslagern
 
Ich denke, ich versteh´s jetzt besser.

Vielen Dank für deine Mühe. :thumb:

user0


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