Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi EXE als DLL Ersatz denkbar? (https://www.delphipraxis.net/58233-exe-als-dll-ersatz-denkbar.html)

choose 3. Dez 2005 16:17


EXE als DLL Ersatz denkbar?
 
Hi,

mit den Win32-Funktionen LoadLibrary und GetProcAddress ist es möglich, eine DLL mit ihrem (Datei-)Namen anzusprechen und exportierte Funktionen und auch sonstige Symbole in den Prozessraum zu laden. Das funktioniert gleichfalls auch mit EXE-Dateien, die ausgewählte Symbole exportieren.

Bei dem Versuch, einen Teil des Funktionsumfangs einer meiner EXE-DAteien auf diese Weise wiederverwendbar zu machen, bin ich jedoch kläglich gescheitert. Zwar wird der erwartete Code wie beschrieben eingebunden und kann uahc ausgeführt werden, anscheinend wird jedoch keiner der Initialisierungsabschnitte der kompilierten Units durchlaufen. Weil große Teile der VCL und der von mir eingesetzten Dritthersteller-Bibliotheken aber genau das erwarten, lassen sich die erfolgreich exportierten Teile nicht sinnvoll nutzen.

Hat jemand von Euch Erfahrung damit und kann mir weiterhelfen?

jim_raynor 3. Dez 2005 17:04

Re: EXE als DLL Ersatz denkbar?
 
VCL und DLLs vertragen sich generell nicht gut. Korrekter wäre es Packages dafür zu erstellen. Aber such mal hier im Forum nach VCL und DLL ;)

DelphiSourcer 4. Dez 2005 08:09

Re: EXE als DLL Ersatz denkbar?
 
Hallo!

Weil das Thema hier grad ist, mich interessiert, wie ich aus einer .EXE Prozeduren und Funktionen exportiere. Für eine Dll ist alles klar, nämlich folgendermaßen:

Delphi-Quellcode:
library MyDll;

uses
  Unit1,Unit2...;

procedure Proc1;
begin
  Machwas;
end;

function Func1: Rückgabetyp;
begin
  Result := Berechnung;
end;

exports
  Proc1,
  Func1;

begin
end;
Wie aber mach ich das bei einer EXE. Einfach, indem ich ein Kompilieren deser DLL als EXE erzwinge, indem ich das in den Compileroptionen einstelle? Oder geht das anders, und wenn ja, wie?

das fragt

DelphiSourcer

himitsu 4. Dez 2005 08:39

Re: EXE als DLL Ersatz denkbar?
 
Zitat:

Zitat von DelphiSourcer
... wie ich aus einer .EXE Prozeduren und Funktionen exportiere.

Du gibt einfach irgendwo (z.B. in der .dpr, oder .pas ...) die gewünschten Funktionen/Prozeduren zum export frei ;)
Also genauso wie es in einer DLL gemacht wird ^^
Delphi-Quellcode:
exports
  Proc1,
  Func1;
Und ich hatte das mal vor ewigen Zeiten dafür genutzt eum eine Datei einmal als normale EXE und wenn nötig auch mal als DLL (in den Explorer integriert) zu verwenden.
Allerdings hatte ich da keine derartigen Probleme? (D4 Std)


Aber im Grunde ist es eigenltich nicht nötig innerhalb einer EXE irgendwelche Prozeduren zu exprotieren.

choose 5. Dez 2005 07:37

Re: EXE als DLL Ersatz denkbar?
 
Zitat:

Zitat von himitsu
ich hatte das mal vor ewigen Zeiten dafür genutzt eum eine Datei einmal als normale EXE und wenn nötig auch mal als DLL (in den Explorer integriert) zu verwenden.
Allerdings hatte ich da keine derartigen Probleme? (D4 Std)

Im allgemeinen Funktioniert dieser Ansatz ja, wie beschrieben, auch bei mir fehlerlos. Problematisch wird es bei Szenarien dieser Art
Delphi-Quellcode:
var
  FReference: TObject;

function GetReference: TObject;
begin
  Result := FReference;
end;

exports
  GetReference;

initialization
  FReference := TSomeClass.Create;

finalization
  FreeAndNil(FReference);

end.
Die Prozedure GetReference kann problemlos genutzt werden und der Code wird fehlerfrei ausgeführt. Leider wird der Initialization-Block jedoch nicht ausgeführt, weshalb die Unit nicht korrekt initialisiert werden kann. In dem skizzierten Beispiel ließe sich das einfach lösen, bei diversen Units von Drittherstellern jedoch nicht mehr ohne weiteres.
Gibt es vielleicht einen speziellen Prozeduraufruf, der die sonst automatisch vorgenommenden Initialisierungen vornimmt?

DerDan 5. Dez 2005 09:36

Re: EXE als DLL Ersatz denkbar?
 
Oder mach doch aus deiner Exe einen ActiveX Server, dann kannst sogar mit JSCript und ähnlichem drauf zugreifen ...

mfg

DerDan

choose 9. Dez 2005 07:51

Re: EXE als DLL Ersatz denkbar?
 
Ein ActiveX-Server ist mir vom Deployment etwas zu aufwendig. Außerdem würde er die erwartete Schnittstelle signifikant verändern.
In meinem Szenario möchte ich Funktionalität über einfache DLLs verfügbar machen. Um die angebotene Logik zeitgleich auch über einen "Doppelklick" anbieten zu können, hatte ich an die Möglichkeit eine EXE zu verwenden gedacht. Ein Algorithmus zum Errechnen, der über eine exportierte Funktion angeboten wird, könnte in der EXE um ein mini-GUI angereichert werden, um die Funktion auch ohne Host-Anwendung nutzen zu können.

Alternativ könnte man eine leichtgewichtige EXE nehmen, deren Funktionalität vollständig auf der DLL basiert, dann jedoch müsste die Schnittstelle der DLL (die Menge der exportierten Funktionen) ggf. erweitert werden, was ich nicht unbedingt möchte. Außerdem ist dieser Ansatz abermals aufwendiger bei der Verteilung.

Eigentlich scheitert der Ansatz nur an der fehlenden Möglichkeit, die Units der EXE zu initialisieren, sobald sie als "DLL" verwendet wird. Das muss doch aber irgendwie gehen :gruebel:

NicoDE 9. Dez 2005 08:28

Re: EXE als DLL Ersatz denkbar?
 
1) Die EPs von Dlls (3 Parameter) sind nicht mit denen von EXEs (4 Parameter) kompatibel.

2) Der Compiler/Linker generiert ja nach Projektart anderen Code (falls du die RTL-Sourcen hast, such in der SysInit.pas nach _InitExe und _InitLib und deren Referenzen).

Ghostwalker 9. Dez 2005 11:11

Re: EXE als DLL Ersatz denkbar?
 
Warum baust du nicht einfach 2 Zusätzliche Funktionen und exportierst sie mit. Diese können das initialisieren bzw. abschließen übernehmen.

Beispiel:

Delphi-Quellcode:
      var
  FReference: TObject;

  function GetReference: TObject;
  begin
    Result := FReference;
  end;
 
   procedure Init;
   begin
     //Wichtig zum Schutz vor mehrfach Initialisierung
     if (freference = NIL) then
        fReference := TSomeClose.create;
   end;

   procedure Done;
   begin
     if (frefrenece <> NIL) then
        freeandnil(freference);
   end;

exports
  GetReference,
  init,
  done;

initialization
  init;

finalization
  done;
Bei Komponenten von Drittherstellern, brauchst du natürlich dafür den source.

choose 9. Dez 2005 11:56

Re: EXE als DLL Ersatz denkbar?
 
Hi,

Ghostwalker, bei Deinem Ansatz muss ich jede Unit so ausstatten. Sehr lästig, weil ich insbesondere die Reihenfolgen ihrer Aufrufe beachten muss...

Zitat:

Zitat von NicoDE
1)Der Compiler/Linker generiert ja nach Projektart anderen Code (falls du die RTL-Sourcen hast, such in der SysInit.pas nach _InitExe und _InitLib und deren Referenzen).

Das war auch mein Ansatzpunkt, dort konnte ich aber leider nicht den Code wiederfinden, der die Units initialisiert. Hast Du einen Ansatz?

schöni 9. Dez 2005 13:32

Re: EXE als DLL Ersatz denkbar?
 
Hallo!

Entschuldigt bitte meine Frage. Zuerst folgender Qouelltext:

Delphi-Quellcode:
program Project3;

{$APPTYPE CONSOLE}

uses
  SysUtils, SysInit, Windows;

procedure Proc1; external 'Project2.exe';
function AValue: Integer; external 'Project2.exe';
procedure Ausgabe(AText: String; AValue: Integer); external 'Project2.exe';

var LibHandle: HINSTANCE; //Wo finde ich diesen Datentyp? Hier bringt der Copiler die
                           //unten stehende Fehlermeldung!

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
  LibHandle := LoadLibrary('Projct2.exe');
  GetProcAddress(LibHandle,'Ausgabe');
  Ausgabe('Dieser Wert lautet: ', 100);
  Readln;
end.
Das hier sagt mir die Delphi Hilfe:

Delphi-Quellcode:
HINSTANCE LoadLibrary(

    LPCTSTR lpLibFileName    // address of filename of executable module
   );
In der Windows Unit scheint der Datentyp nicht definiert zu sein.

Vom Compiler kriege ich folgende Fehlermeldung:

[Fehler] Project3.dpr(12): Konstante oder Typenbezeichner erwartet

Was soll das??? Die Hilfe sagt mir, das dert Typ HINSTANCE in der Unit System definiert ist und die wird doch eh automatisch mit eingebunden? Aufführen der System-Unit führt auch nicht zum Erfolg. Was kann ich hier machen, damit der Code funzt.

Hier ist noch der Code für die Bibliothek mit den zu exportierenden Routinen:

Delphi-Quellcode:
program Project2; //Enthält die zu exportierenden Routinen. (als EXE übersetzt)

{$APPTYPE CONSOLE}

uses
  SysUtils, SysInit, Windows;

procedure Proc1;
begin
   writeln('Aufruf der ersten Prozedur war erfolgreich!');
end;

function AValue: Integer;
begin
   Result := 4;
end;

procedure Ausgabe(AText: String; AValue: Integer);
begin
   writeln(AText, AValue);
end;

exports
  Proc1,
  AValue,
  Ausgabe;

begin

end.
Wenn ich das ohne LoadLibrary versuche, erhalte ich von Windows folgende Meldung:

"Die Datei Project3.exe ist verknüpft mit dem fehlenden Export Project2.exe Ausgabe".

Deshalb gehe ich davon aus, das ich, wenn ich das mit ner EXE statt mit ner DLL machen will, unbedingt mit LoadLibrary arbeiten muss. Aber da meckert der Compiler wegen HINSTANCE mit obiger Compilermeldung.

Was mache ich falsch? Weiß nicht mehr weiter.


schöni

NicoDE 9. Dez 2005 14:43

Re: EXE als DLL Ersatz denkbar?
 
Zitat:

Zitat von choose
Das war auch mein Ansatzpunkt, dort konnte ich aber leider nicht den Code wiederfinden, der die Units initialisiert. Hast Du einen Ansatz?

Ansatz schon, aber leider ist das mit einer umfangreichen Änderung der RTL verbunden (davon würde ich abraten).

schöni 9. Dez 2005 15:13

Re: EXE als DLL Ersatz denkbar?
 
Ich hab auch keinen Ansatz, oder doch, bloß funzen tut's nich.

Hier meine Bibliothek als EXE. Deshalb das Wort Pprogram, statt Library.

Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure Proc1; stdcall;
begin
  writeln('Erste Prozedur aus der Bibliothek erfolgreich aufgerufen!');
end;

function AValue: Integer; stdcall;
begin
   Result := 4;
end;

procedure Ausgabe(AText: String; AValue: Integer); stdcall;
begin
   writeln(AText,AValue);
end;

exports
  Proc1 Index 1,
  AValue Index 2,
  Ausgabe Index 3;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
end.
Und hier die Anwendung, welche die Bibliothek verwendet:

Delphi-Quellcode:
program Project3;

{$APPTYPE CONSOLE}

uses
  ShareMem, System, SysUtils, SysInit, Windows;

type
  TFarProc = procedure(T: String; I: Integer);

procedure Proc1; stdcall external 'Project2.exe' Index 1;
function AValue: Integer; stdcall external 'Project2.exe' Index 2;
procedure Ausgabe(AText: String; AValue: Integer); stdcall external 'Project2.exe' Index 3;

var ProcHandle: FarProc;
    Proc: TFarProc;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }
  HINSTANCE := LoadLibrary('Projct2.exe');
  ProcHandle := GetProcAddress(HINSTANCE,'Ausgabe');
  Proc := TFarProc(ProcHandle);
  Proc('Dieser Wert lautet: ', 100);
  Readln;
end.
Felermeldung von Windows:

PROJECT3 verursachte einen Fehler durch eine ungültige Seite
in Modul <Unbekannt> bei 00de:bff90777.
Register:
EAX=81dfba60 CS=81dfd04c EIP=bff90777 EFLGS=bff741f7
EBX=81d33e0c SS=bff7dafa ESP=81dfc048 EBP=0063ff6c
ECX=bff741f7 DS=0040 ESI=00000008 FS=bff7a567
EDX=00000000 ES=81d02000 EDI=81dde84c GS=bff7a10e
Bytes bei CS:EIP:

Stapelwerte:

Ich kann mir nicht erlklären, was ich falsch gemacht habe. Kann mir jemand helfen?

schöni

Ghostwalker 10. Dez 2005 07:57

Re: EXE als DLL Ersatz denkbar?
 
Das ist sehr einfach, du exportierst eine Funktion mit einem Delphi-String-Parameter. Um das nutzen zu können mußt du die Unit Sharemem von Borland mit einkompilieren, sonst kann er mit den Strings nichts anfangen.

Erstell einfach mal ein DLL-Projekt, dort wird ein entsprechender Hinweis als Kommentar mit erstellt.

schöni 12. Dez 2005 10:39

Re: EXE als DLL Ersatz denkbar?
 
Zitat:

Zitat von Ghostwalker
Das ist sehr einfach, du exportierst eine Funktion mit einem Delphi-String-Parameter. Um das nutzen zu können mußt du die Unit Sharemem von Borland mit einkompilieren,

Wirklich! Danke aber auch. Guck mal in den Beitrag von mir! Meinst Du jene Unit, die als erstes aufgeführt ist??? Wenn ja, muß noch was anderes faul sein. Die ist nämlich aufgeführt. In der DLL UND in der DPR. Trotzdem Fehler. Also doch ein Dll Projekt als EXE übersetzen. Ist LIBRARY das Zauberwort, anstelle PROGRAM?

Wenn das alles so einfach ist, warum wird dann der entscheidende Tipp nicht einfach gepostet?

Delphi-Quellcode:
uses
  ShareMem, System, SysUtils, SysInit, Windows;
Das habe ich aus meiner aktuellen .dpr - Datei rauskopiert. Mein Fehler muß also doch noch ne andere Ursache haben! In der zu exportierenden Bibliothek ist nämlich ShareMem auch aufgeführt und zwar an erster Stelle. Werde mal ein Dll Projekt erstellen. Und versuchen, die Dll als EXE zu übersetzen, denn genau darum geht es mir. Ich brauch eine .EXE, die wie eine .dll Routinen exportieren kann.

schöni

DelphiSourcer 12. Dez 2005 10:53

Re: EXE als DLL Ersatz denkbar?
 
Hallo!

Ich hab zwar noch keine Routinen exportierende EXE hingekrigt, aber ein Dll Projekt kann zumindest mal als .OBJ Datei für C oder C++ übersetzt werden. Die läßt sich bekanntlich per [$Link ...] bzw. {$L ...} Direktive in den Programmtext einbinden, womit das eigentliche Ziel, Routinen allgemein verfügbar zu machen, genauso gewährleistet wird. Ziel damit auch erreicht, Punkt!

DelphiSourcer

schöni 12. Dez 2005 12:57

Re: EXE als DLL Ersatz denkbar?
 
Zitat:

Zitat von DelphiSourcer
...ein Dll Projekt kann zumindest mal als .OBJ Datei für C oder C++ übersetzt werden. Die läßt sich bekanntlich per [$Link ...] bzw. {$L ...} Direktive in den Programmtext einbinden...

JUHUUUU..., das geht natürlich auch. Scheint ja mit ner EXE statt DLL doch nich so "einfach" zu sein, sonst wäre ja die Antwort längst eindeutig ausgefallen. Dort, wo DLLs nicht unterstützt werden, muss dann halt ne .OBJ Datei verwendet werden.

Außerdem wird ne .EXE mit dem Schlüsselwort "PROGRAM" eingeleitet, ne .DLL dagegen mit "LIBRARY" und letzere läßt sich eben NICHT als EXE übersetzen, sondern ausschließlich als DLL.
Ich habe die Unit "ShareMem eingebunden und die .EXE mit den exportierten Routinen läßt sich nicht einbinden. EXE als DLL scheint also NICHT zu funktionieren, ich kriege nämlich trotz eingebundener ShareMem-Unit die Fehlermeldung, aber mit .OBJ geht es ja auch. Da kann ich ne Unit erstellen, die diese .OBJ Datei verwendet und habe das gleiche erreicht, falls vom Compiler, für den ich die Routinen exportieren will, DLLs nicht unterstützt werden. Manchmal muss man halt bissl um die Ecke denken. Dann ergeben sich Problemlösungen auch auf unerwartete Weise. Werd mich gleich mal dranmachen.

"Dumm kan man ruhig sein, man muß sich nur zu helfen wissen!"

Gruß

schöni


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