Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi DLL nicht automatisch laden (https://www.delphipraxis.net/205116-dll-nicht-automatisch-laden.html)

venice2 2. Aug 2020 23:22

DLL nicht automatisch laden
 
Ich habe eine DLL erstellt die nur geladen werden soll wenn die Bedingung true ist.

Delphi-Quellcode:
  if UseDebug then
  begin
    if not InitTrace then
    begin
      hTrace := LoadLibrary('Tracer.dll');
      if hTrace <> 0 then
        InitTrace := True;
    end;
  end;
Das funktioniert soweit aber!
Sobald ich eine Funktion der DLL im Code implementiere lädt die DLL automatisch.

Delphi-Quellcode:
Trace(PWideChar('Init ' + 'Value = ' + BoolToStr(bInit)));


Deaktiviere ich diese Zeile dann geht es so wie ich will.

Wie kann ich das verhindern?

himitsu 2. Aug 2020 23:57

AW: DLL nicht automatisch laden
 
Zitat:

Zitat von venice2 (Beitrag 1471026)
Sobald ich eine Funktion der DLL im Code implementiere lädt die DLL automatisch.

Und wie ist diese Funktion implementiert?

Bei LoadLibrary mit GetProcAddress, kann sowas nicht passieren.


Wenn du aber einen statischen Link mit dem dynamischen Laden mischst, dann bisst'e selbst Schuld.

> entweder dynamisch oder statisch, aber niemals Beises



Im Windows kann man inzwischen eine external-Deklaration mit delayed mischen
und bekommt die dritte Variante.

statisch
"statische" deklaration mit automatisch dynamischen Laden
und manuell "dynamisch" (LoadLibrary)

http://docwiki.embarcadero.com/RADSt...ckages_(Delphi)

venice2 3. Aug 2020 00:08

AW: DLL nicht automatisch laden
 
Zitat:

Zitat von himitsu (Beitrag 1471027)
Zitat:

Zitat von venice2 (Beitrag 1471026)
Sobald ich eine Funktion der DLL im Code implementiere lädt die DLL automatisch.

Und wie ist diese Funktion implementiert?

Delphi-Quellcode:
procedure TraceDebug(Msg: PWideChar); stdcall;
function Trace(Tmp: PWideChar): LongInt; stdcall;
Delphi-Quellcode:
library Tracer;

{ 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
  Windows,
  SysUtils,
  Global in 'Global.pas',
  uIni in 'uIni.pas';

{$R *.res}
  procedure LibraryProc(Reason: integer);
  begin
    case (Reason) of
      //DLL_PROCESS_ATTACH:
      //  Trace('Trace Init'); // DLL Funktion aufgerufen bevor ich die geladen habe, also deaktiviert.
     
      DLL_PROCESS_DETACH:
        begin
         if gnBackBrush <> 0 then
         begin
           DeleteObject(gnBackBrush);
           gnBackBrush := 0;
         end;
         TraceDebug('');
        end;
    end;
  end;

exports
  Trace,
  TraceDebug;

begin

  DLLProc := @LibraryProc;
  DLLProc(DLL_PROCESS_ATTACH);
end.
Hat sich erledigt siehe Kommentar.

venice2 3. Aug 2020 10:02

AW: DLL nicht automatisch laden
 
Muss nochmal nachhaken.
Warum kann ich in C++ Funktionen einer DLL aufrufen die sich nicht im Anwendungspfad befindet bzw. Kann meine Exe starten obwohl diese DLL fehlt.

In Delphi kann ich meine Anwendung gar nicht erst starten wenn die DLL nicht vorhanden ist.
Was macht Delphi im Gegensatz zu C++ da anders? Delphi einfach zu dumm? Oder ich.

Uwe Raabe 3. Aug 2020 10:13

AW: DLL nicht automatisch laden
 
Eine statisch gelinkte DLL wird beim Start der EXE gesucht. Welche Orte dabei durchsucht werden ist irgendwo in der Windows-Doku beschrieben (hab es gerade nicht parat). Das ist übrigens nicht irgendwas von Delphi sondern es ist Windows, das so arbeitet.

venice2 3. Aug 2020 10:15

AW: DLL nicht automatisch laden
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1471037)
Eine statisch gelinkte DLL wird beim Start der EXE gesucht. Welche Orte dabei durchsucht werden ist irgendwo in der Windows-Doku beschrieben (hab es gerade nicht parat). Das ist übrigens nicht irgendwas von Delphi sondern es ist Windows, das so arbeitet.

Sie wird auch statisch in C++ gelinkt.
Was soll mir das jetzt sagen.
Es geht mir nicht um den Ort sondern das mein Programm in C++ startet in Delphi aber nicht.
Unabhängig davon wo sich die DLL befindet. Bzw. Nicht vorhanden ist.

C++
1. DLL statisch gelinkt.
2. Funktionen sind im Quellcode aktiv und werden auch aufgerufen.
3. Anwendung startet.
4. Funktionen die aufgerufen werden gehen ins leere wenn das Handle der DLL über LoadLibrary 0 ist.

Delphi
1. DLL statisch gelinkt.
2. Funktionen sind im Quellcode aktiv und werden aufgerufen und starten die DLL automatisch (Warum? )
3. Anwendung startet nicht wenn DLL fehlt
4. Funktionen die aufgerufen werden starten die DLL automatisch ohne das ich LoadLibrary selbst verwende. (Warum? )

Weshalb lädt der Compiler die DLL selbst (bzw. sucht diese) ohne mein Zutun und ignoriert diese nicht einfach so wie es in C++ auch der Fall ist?

Es geht nicht um die Frage statisch oder Dynamisch sondern warum beim statischen linken C++\Delphi so einen unterschied machen.

Uwe Raabe 3. Aug 2020 11:03

AW: DLL nicht automatisch laden
 
Zitat:

Zitat von venice2 (Beitrag 1471038)
Weshalb lädt der Compiler die DLL selbst (bzw. sucht diese) ohne mein Zutun und ignoriert diese nicht einfach so wie es in C++ auch der Fall ist?

Der Compiler lädt weder eine DLL nocht sucht er diese - das tut Windows wenn das Programm gestartet wird und noch bevor irgendein OpCode der EXE ausgeführt wird.

Es ist aber auch durchaus möglich, daß statisches Linken in C++ etwas anderes bedeutet als statisches Linken einer DLL in Delphi. Vielleicht werden vom C++ Compiler die externen Routinen statisch in das Programm einkopiert (z.B. aus obj-Dateien oder einer lib-Datei). Dann braucht das C++ Programm die DLL gar nicht da es den Code bereits enthält. Ich bin aber nun mal kein C++ Experte. Deswegen ist das nur eine Vermutung.

venice2 3. Aug 2020 11:08

AW: DLL nicht automatisch laden
 
Zitat:

(z.B. aus obj-Dateien oder einer lib-Datei). Dann braucht das C++ Programm die DLL gar nicht da es den Code bereits enthält.
Danke Uwe für die Infos.

Aber!
Ein ein kompilieren der *.lib bringt in dem Fall gar nichts ohne entsprechender DLL startet die Funktion gar nicht erst.
Aber die Anwendung was in Delphi nicht der Fall ist.

Ich möchte aber nur weil die DLL nicht vorhanden ist nicht alle aufrufe der DLL Funktionen wieder deaktivieren. (ja ich könnte sie Dynamisch laden tue ich aber in C++ auch nicht)
In C++ geht das doch auch.
Und ja selbst getestet.

Zitat:

das tut Windows
Selbst wenn Windows das tut muss es dennoch einen Unterschied geben das es mit C++ funktioniert aber in Delphi nicht.

Aktiviere ich diese Zeile.
Delphi-Quellcode:
      DLL_PROCESS_ATTACH:
       Trace('Trace Init');
Dann wird die DLL automatisch geladen ohne das ich LoadLibrary dafür bemühe.
Das soll sie aber nicht.

Dalai 3. Aug 2020 12:08

AW: DLL nicht automatisch laden
 
So ganz ohne Code (und ggf. Compilerschalter), sowohl für C++ als auch für Delphi, ist das alles nur Rumgerate. Du solltest außerdem mal einen Blick auf die Importtable der EXE schauen, welche DLLs und welche Funktionen sie daraus holt/erfordert - dafür gibt es zahlreiche Programme (ich nutze Total Commander Lister Plugins PE Viewer und FileInfo). Ein Aufruf einer Funktion aus einer externen DLL in Delphi, die nicht
Delphi-Quellcode:
delayed;
ist und nicht dynamisch per GetProcAddress/LoadLibrary gerufen wird, findet sich immer als erforderlicher Funktionsruf in der Importtabelle wieder - fehlt die DLL, gibt Windows eine entsprechende Meldung, welche DLL fehlt und bricht den Start des Programms ab.

Dr Bob hat eine ganz gute Zusammenfassung der Möglichkeiten und Unterschiede:
http://www.drbob42.com/examines/examinC1.htm

Grüße
Dalai

venice2 3. Aug 2020 12:12

AW: DLL nicht automatisch laden
 
Zitat:

So ganz ohne Code
Ganz ohne. Hast du ihn für Delphi übersehen?

Eine DLL Dynamisch zu laden ist nicht das Problem und damit geht es auch. (ganz so dumm bin ich dann doch nicht!) :)
Nur wie gesagt verstehe nicht das es mit einer statisch geladenen DLL in C++ funktioniert und in Delphi halt nicht.

Delphi-Quellcode:
unit Dynamic_Trace;

interface

uses Windows;

const
  dllfile = 'Tracer.dll';

var
  TRACE_Handle: Thandle = 0;
  Trace_Loaded: Bool = false;

  Trace: function(Msg: PWideChar): LongInt; stdcall;

function Load_TRACEDLL(const dllfilename: string): BOOL;
procedure Unload_TRACEDLL;

implementation

function Load_TRACEDLL(const dllfilename: string): BOOL;
var
  oldmode: integer;
begin
  if TRACE_Handle <> 0 then
    Result := true
  else
  begin
    oldmode := SetErrorMode($8001);
    TRACE_Handle := LoadLibrary(PWideChar(dllfilename));
    SetErrorMode(oldmode);
    if TRACE_Handle <> 0 then
    begin
      @Trace := GetProcAddress(TRACE_Handle, PAnsiChar('Trace'));
      if (@Trace = nil) then
      begin
        FreeLibrary(TRACE_Handle);
        TRACE_Handle := 0;
      end;
    end;
    Result := (TRACE_Handle <> 0);
  end;

end;

procedure Unload_TRACEDLL;
var
  HWND: DWord;
begin
  if TRACE_Handle <> 0 then
  begin
    HWND := FindWindow('TRACER', 'TRACER');
    if HWND <> 0 then
    begin
      TRACE_Handle := SendMessage(HWND, WM_DESTROY, 0, 0);
      Trace_Loaded := false;
    end else
    begin
      TRACE_Handle := 0;
      Trace_Loaded := false;
    end;
  end;
end;

end.
Delphi-Quellcode:
  if UseDebug then
  begin
    if not Trace_Loaded then
    begin
      Trace_Loaded := Load_TRACEDLL(ExtractFilePath(paramstr(0)) +
        dllfile);
      if Trace_Loaded then
      begin
        Trace('');
        repeat
          HWND := FindWindow('TRACER', 'TRACER');
          WinprocessMessages;
        until HWND <> 0;
      end;
    end;
  end;
Und der Aufruf.

Delphi-Quellcode:
if Trace_Loaded then
  Trace(PWideChar('Init ' + 'Value = ' + BoolToStr(bInit)));
So startet die Anwendung auch wenn die DLL nicht existiert.

Aber meine Frage ist damit nicht beantwortet denn ich verwende so Dynamisches und kein statisches laden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:48 Uhr.
Seite 1 von 2  1 2      

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