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/)
-   -   Wie lade ich eine DLL zur Laufzeit. (https://www.delphipraxis.net/215886-wie-lade-ich-eine-dll-zur-laufzeit.html)

wschrabi 21. Sep 2024 09:53


Wie lade ich eine DLL zur Laufzeit.
 
Liebe Freunde,
ich habe hier:
Delphi-Quellcode:
procedure TForm1.FormCreateHOOK;
begin
  // Laden der DLL
  //DLLHandle := LoadLibrary(Extractfilepath(Application.exename)+'MouseHookDLL.dll');
  DLLHandle := winapi.windows.LoadLibrary('DLLMouseHook.dll');
  if DLLHandle <> 0 then
  begin
    // Setzen des globalen Hooks mit der in der DLL definierten Prozedur
    @MouseHookProc := GetProcAddress(DLLHandle, 'MouseHookProc');
    if Assigned(@MouseHookProc) then
    begin
      MouseHook := SetWindowsHookEx(WH_MOUSE_LL, @MouseHookProc, DLLHandle, 0);
      if MouseHook = 0 then
        ShowMessage('Failed to set hook: ' + SysErrorMessage(GetLastError));
    end;
  end;
end;
mit den USES im Programm:
Delphi-Quellcode:
unit MainUnit1;

interface

uses
  Winapi.windows, Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  DateUtils, Grids,
  SHDocVw, MSHTML, ActiveX,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls, WebView,
   Vcl.OleCtrls;
Meine DLL ist im Selben Verzeichnis wie meine EXE (32bit)
und sieht so aus:
Delphi-Quellcode:
library DLLMouseHOOK;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss die erste
  Unit in der USES-Klausel Ihrer Bibliothek UND in der USES-Klausel Ihres Projekts
  (wählen Sie 'Projekt-Quelltext anzeigen') sein, wenn Ihre DLL Prozeduren oder Funktionen
  exportiert, die Strings als Parameter oder Funktionsergebnisse übergeben. Dies
  gilt für alle Strings, die an oder von Ihrer DLL übergeben werden, auch für solche,
  die in Records und Klassen verschachtelt sind. ShareMem ist die Interface-Unit zur
  gemeinsamen BORLNDMM.DLL-Speicherverwaltung, die zusammen mit Ihrer DLL
  weitergegeben werden muss. Übergeben Sie String-Informationen mit PChar- oder ShortString-Parametern, um die Verwendung von BORLNDMM.DLL zu vermeiden.
 }

uses
  Windows,
  Messages,
  SysUtils,
  Classes;

{$R *.res}

var
  MouseHook: HHOOK;

function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if nCode = HC_ACTION then
  begin
    // Hier können Sie die Mausereignisse verarbeiten
    // Beispiel: Wenn die linke Maustaste gedrückt wird
    if wParam = WM_LBUTTONDOWN then
    begin
      // Mauskoordinaten oder andere Aktionen hier verarbeiten
      MessageBox(0, 'Linke Maustaste gedrückt', 'Maus-Hook', MB_OK);
    end;
  end;
  Result := CallNextHookEx(MouseHook, nCode, wParam, lParam);
end;

exports
  MouseHookProc;

begin
end.
Doch Delphi 10.1 Compiliert nicht und bekommen den Error) "[dcc32 Fehler] MainUnit1.pas(158): E2036 Variable erforderlich",
bei der Zeile
Delphi-Quellcode:
    // Setzen des globalen Hooks mit der in der DLL definierten Prozedur
    @MouseHookProc := GetProcAddress(DLLHandle, 'MouseHookProc');
Ich weiß nicht wieso?:oops:
Danke für Jeden TIPP:

wschrabi 21. Sep 2024 10:08

AW: WIe kann ich von der DLL zwei Integerwerte (X,Y) in das Hauptprogramm übergeben?
 
Hab' schon: :-D
das hat gefehlt.
Delphi-Quellcode:
type
  TMyProcedure = procedure; stdcall;

var
  MyMouseHookProc: TMyProcedure;
und im Implementations Teil:
Delphi-Quellcode:
procedure TForm1.FormCreateHOOK;
begin
  // Laden der DLL
  //DLLHandle := LoadLibrary(Extractfilepath(Application.exename)+'MouseHookDLL.dll');
  DLLHandle := winapi.windows.LoadLibrary('DLLMouseHook.dll');
  if DLLHandle <> 0 then
  begin
    // Setzen des globalen Hooks mit der in der DLL definierten Prozedur
    @MyMouseHookProc := GetProcAddress(DLLHandle, 'MouseHookProc');
    if Assigned(@MyMouseHookProc) then
    begin
      MouseHook := SetWindowsHookEx(WH_MOUSE_LL, @MyMouseHookProc, DLLHandle, 0);
      if MouseHook = 0 then
        ShowMessage('Failed to set hook: ' + SysErrorMessage(GetLastError));
    end;
  end;
end;
Doch noch eine FRAGE:

WIe kann ich von der DLL zwei Integerwerte (X,Y) in das Hauptprogramm übergeben?
DANKE

wschrabi 21. Sep 2024 10:11

AW: Wie lade ich eine DLL zur Laufzeit.
 
Habs:
Um von einer DLL zwei Integer-Variablen an das aufrufende Hauptprogramm zu übergeben, können Sie eine Funktion in der DLL definieren, die diese Variablen als `var`-Parameter zurückgibt. Hier ist ein vollständiges Beispiel, das zeigt, wie Sie dies in Delphi umsetzen können.

### Schritt 1: Erstellen der DLL

Definieren Sie eine Funktion in der DLL, die zwei Integer-Variablen über `var`-Parameter zurückgibt.

Delphi-Quellcode:
library ExampleDLL;

uses
  SysUtils, Classes;

procedure GetCoordinates(var X, Y: Integer); stdcall;
begin
  // Beispielwerte für X und Y
  X := 100;
  Y := 200;
end;

exports
  GetCoordinates;

begin
end.


### Schritt 2: Verwenden der DLL im Hauptprogramm

Laden Sie die DLL im Hauptprogramm und rufen Sie die Funktion auf, um die Werte zu erhalten.

Delphi-Quellcode:
uses
  Windows, SysUtils;

type
  TGetCoordinates = procedure(var X, Y: Integer); stdcall;

var
  DLLHandle: THandle;
  GetCoordinates: TGetCoordinates;
  X, Y: Integer;
begin
  // Laden der DLL
  DLLHandle := LoadLibrary('ExampleDLL.dll');
  if DLLHandle = 0 then
    raise Exception.Create('Could not load the DLL: ' + SysErrorMessage(GetLastError));

  try
    // Adresse der Funktion abrufen
    @GetCoordinates := GetProcAddress(DLLHandle, 'GetCoordinates');
    if not Assigned(GetCoordinates) then
      raise Exception.Create('Could not find the function in the DLL');

    // Funktion aufrufen und die Werte erhalten
    GetCoordinates(X, Y);

    // Ausgabe der erhaltenen Werte
    WriteLn(Format('Received coordinates: X = %d, Y = %d', [X, Y]));
   
  finally
    // Freigeben der DLL
    if DLLHandle <> 0 then
      FreeLibrary(DLLHandle);
  end;
end.

### Wichtige Hinweise:
- **Calling Convention**: Stellen Sie sicher, dass sowohl in der DLL als auch im Hauptprogramm die gleiche Calling Convention (`stdcall`) verwendet wird.
- **Fehlerbehandlung**: Überprüfen Sie immer den Rückgabewert von `LoadLibrary` und `GetProcAddress`, um sicherzustellen, dass die Operationen erfolgreich waren.
- **Ressourcenmanagement**: Denken Sie daran, die DLL mit `FreeLibrary` freizugeben, wenn sie nicht mehr benötigt wird.

Dieses Beispiel zeigt eine einfache Möglichkeit, wie Daten von einer DLL an ein Hauptprogramm übergeben werden können. Die Verwendung von `var`-Parametern ermöglicht es Ihnen, Werte direkt zu ändern und an den Aufrufer zurückzugeben.

himitsu 21. Sep 2024 12:10

AW: Wie lade ich eine DLL zur Laufzeit.
 
Zitat:

Zitat von wschrabi (Beitrag 1541335)
E2036 Variable erforderlich"

Ist aber auch richtig.

@MyMouseHookProc
Da gehört nirgendwo ein @ hin.

Höchstens andersrum, als MyMouseHookProc^, aber auch das ist nicht nötig, da beim Aufruft, durch die ( ) implizit dereferenziert wird.

Bernhard Geyer 21. Sep 2024 13:40

AW: Wie lade ich eine DLL zur Laufzeit.
 
Schau dir mal das Delayed loading von aktuellen Delphies an:
https://docwiki.embarcadero.com/Code...oading_(Delphi)

Würde DLLs, welche nicht zwingend vorhanden sind, nur noch so einbinden.

DaCoda 21. Sep 2024 17:04

AW: Wie lade ich eine DLL zur Laufzeit.
 
Versuche es doch mal so:

Code:
const
  mydll = 'DLLMouseHook.dll';


function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM); external mydll;


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 Uhr.

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