AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Mutex-Handling in DLL für zwei Programme
Thema durchsuchen
Ansicht
Themen-Optionen

Mutex-Handling in DLL für zwei Programme

Ein Thema von TheSledgeHammer · begonnen am 22. Mai 2019 · letzter Beitrag vom 23. Mai 2019
Antwort Antwort
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#1

Mutex-Handling in DLL für zwei Programme

  Alt 22. Mai 2019, 14:18
Hallo Community,

ich sitze hier gerade an einem sehr "interessanten" (man könnte auch nervig dazu sagen...) Phänomen, das ich mir nicht so recht erklären kann.

Zunächst mal kurz die Motivation:
Es gibt hier zwei Prozesse, die sich eine INI-Datei teilen. Der eine Prozess ist eine EXE-Datei in Delphi geschrieben (32 bit), der andere ist ein Matlab-Skript. Beide Prozesse schreiben und lesen diese INI-Datei, daher ist eine Synchronisation absolut notwendig. Das wollte ich mit einer DLL realisieren, die einen Mutex erzeugt. Eine DLL deshalb, weil Matlab wohl das Prinzip der Mutexe nicht unterstützt und ich dem Entwickler somit dieselbe Funktionalität zur Verfügung stellen kann.

Es gibt 4 Methoden, die die DLL zur Vefügung stellt: Register, UnRegister, Acquire und Release. In der DLL wiederum gibt es eine globale Variable FMutex (Vom Typ System.SyncObj.TMutex), die über die komplette Laufzeit hinweg gehalten wird. Register macht ein Create, UnRegister ein Free und Acquire bzw. Release sind ja selbsterklärend.

Jetzt kommt der Clou: Wenn ich diese 4 Methoden einfach im Delphi-Programm "hart rein programmiere", dann klappt das alles wie am Schnürchen. Sobald diese Methoden aber in der DLL stehen und aufgerufen werden, fliegt mir das Programm um die Ohren wie eine Kuh bei einem Tornado.

Hier mal die DLL:
Delphi-Quellcode:
uses
  System.SysUtils,
  System.Classes,
  System.SyncObjs;

{$R *.res}

var
  FMutex: TMutex;

procedure RegisterMutex(); stdcall;
begin
  if not Assigned(FMutex) then
    FMutex := TMutex.Create(nil, false, 'MyUniqueMutexName');
end;

procedure UnRegisterMutex(); stdcall;
begin
  if Assigned(FMutex) then
    FMutex.Free;
end;

procedure AcquireMutex(); stdcall;
begin
  if Assigned(FMutex) then
    FMutex.Acquire;
end;

procedure ReleaseMutex(); stdcall;
begin
  if Assigned(FMutex) then
    FMutex.Release;
end;

exports
  RegisterMutex,
  UnRegisterMutex,
  AcquireMutex,
  ReleaseMutex;

begin
end.
In dem Delphi-Programm, das ich auch entwickle, lade ich die DLL mittels LoadLibrary und hole mir die 4 Methoden über GetProcAddress. Die rufe ich dann an den entsprechenden Stellen auf.

Hat irgendwer von euch schon Mal so ein Konstrukt gebaut oder verwendet?
Tobias

Geändert von TheSledgeHammer (22. Mai 2019 um 15:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.667 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Mutex-Handling in DLL für zwei Programme

  Alt 22. Mai 2019, 14:48
Jetzt kommt der Clou: Wenn ich diese 4 Methoden einfach im Delphi-Programm "hart rein programmiere", dann klappt das alles wie am Schnürchen. Sobald diese Methoden aber in der DLL stehen und aufgerufen werden, fliegt mir das Programm um die Ohren wie eine Kuh bei einem Tornado.
Was genau ist der Fehler? Ich glaube kaum, dass beim Start des Programms starker Wind auftritt und vierbeinige Nutztiere durch die Gegend fliegen.
Thomas Mueller
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Mutex-Handling in DLL für zwei Programme

  Alt 22. Mai 2019, 15:05
Nein, auch wenn wir hier Geräte herstellen, die durchaus genug Wind erzeugen könnten, damit so etwas passiert, ist das nicht der Fall

Das schöne (oder eher schlimme) ist, dass keine Fehlermeldung erscheint, sonst hätte ich sie ja mit dazu geschrieben. Aus Sicht des Anwenders kommt aus heiterem Himmel "Programm reagiert nicht mehr und muss geschlossen werden". Ich habe den Absturz zwar lokalisieren können, aber es macht keinen wirklichen Sinn:

Nach dem Laden der DLL wird die Register-Funktion aufgerufen (klappt), danach kommt ein Acquire (geht auch noch) und ein Release (klappt auch) und selbst das UnRegister scheint zu klappen (laut Debug-Ausgaben). Nur in dem Moment, in dem die UnRegister Funktion verlassen wird, knallt's.
Tobias
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.071 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Mutex-Handling in DLL für zwei Programme

  Alt 22. Mai 2019, 15:11
Minimales Beispielprojekt zum Nachvollziehen?
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Mutex-Handling in DLL für zwei Programme

  Alt 22. Mai 2019, 15:19
Minimales Beispielprojekt zum Nachvollziehen?
Ich werde mal die Methoden hier rein schreiben, die notwendig wären, das wird so 1:1 nicht laufen.

Delphi-Quellcode:

TMyDllProc = procedure() of object; stdcall;

TExampleClass = class(TThread)
  private
    FHandleDLL: THandle;
    // methods from DLL
    FRegister: TMyDllProc;
    FUnRegister: TMyDllProc;
    FAcquire: TMyDllProc;
    FRelease: TMyDllProc;

    function InitMutexDLL(): boolean;
    procedure DeInitMutexDLL();
    procedure ExecuteMutex();

    procedure Execute(); override;
end;

// ...

function TExampleClass.InitMutexDLL(): boolean;
begin
 
  Result := false;
  FHandleDLL := LoadLibrary(PChar('MutexDLL.dll'));

  if FHandleDLL <> INVALID_HANDLE_VALUE then
  begin

    @FRegister := GetProcAddress(FHandleDLL, 'RegisterMutex');
    @FAcquire := GetProcAddress(FHandleDLL, 'EnterMutex');
    @FRelease := GetProcAddress(FHandleDLL, 'ReleaseMutex');
    @FUnregister := GetProcAddress(FHandleDLL, 'UnRegisterMutex');

    Result := Assigned(FRegister) and Assigned(FAcquire) and Assigned(FRelease) and Assigned(FUnregister);

    if Result then
      FRegister();

  end;

end;

// ...

procedure TExampleClass.DeInitMutexDLL();
begin

  if FHandleDLL <> INVALID_HANDLE_VALUE then
  begin
    FUnRegister();
    FreeLibrary(FHandleDLL);
  end;

end;

// ...

procedure TExampleClass.ExecuteMutex();
begin

  try
    FAcquire();
    // access INI-File
  finally
    FRelease();
  end;

end;

// ...

procedure TExampleClass.Execute();
begin
  InitMutexDLL();
  while not Terminated do
  begin
    ExecuteMutex();
    Sleep(100)
  end;
  DeInitMutexDLL();
end;
Tobias

Geändert von TheSledgeHammer (22. Mai 2019 um 15:24 Uhr)
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
711 Beiträge
 
Delphi 12 Athens
 
#6

AW: Mutex-Handling in DLL für zwei Programme

  Alt 22. Mai 2019, 16:39
Minimales Beispielprojekt zum Nachvollziehen?
Ich werde mal die Methoden hier rein schreiben, die notwendig wären, das wird so 1:1 nicht laufen.

Delphi-Quellcode:

TMyDllProc = procedure() of object; stdcall;
Die Deklaration ist falsch, die von der DLL exportierten Methoden sind nicht "of object"!
Mit deiner obigen Deklaration wird beim Aufruf ein zusätzlicher Parameter (Self) übergeben, den die DLL aber nicht erwartet. Das bringt den Call-Stack durcheinander.
Peter Below
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:05 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 by Thomas Breitkreuz