AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL neu starten nach beenden

Ein Thema von EWeiss · begonnen am 20. Okt 2010 · letzter Beitrag vom 4. Nov 2010
Antwort Antwort
Seite 1 von 2  1 2      
EWeiss
(Gast)

n/a Beiträge
 
#1

DLL neu starten nach beenden

  Alt 20. Okt 2010, 13:21
Ich habe eine Vis geschrieben mit 3 Modulen
Winamp stellt die möglichkeit zur verfügung die Module über einen Button vor, zurück oder zufällig zu starten.
Mein problem ist nur wenn ich ein Modul beendet habe kann ich kein neues innerhalb der DLL auswählen
weil sich diese dadurch beendet.

Ich muss quasi die Module1_Quit aufrufen zum beenden
procedure _Cover_Quit(This_Mod: PWinAMPVisModule); cdecl; um danach das neue mit
Module1_Init zu aktivieren.

Nur wie stelle ich das an wenn die DLL dadurch beendet wird?

In einer Anwendung kann ich ja unterbinden das sie doppelt gestartet wird
Delphi-Quellcode:
initialization
  hMutex := CreateMutex(nil, True, 'Global\Soundmachine');
  if GetLastError = ERROR_ALREADY_EXISTS then
    Halt;

finalization
  if hMutex <> 0 then
    CloseHandle(hMutex)
Gibt es sowas ähnliches damit sich meine DLL selbst wieder aufruft bzw.. gar nicht erst beendet?

Ich hoffe ihr versteht was ich damit meine.

gruss

Geändert von EWeiss (20. Okt 2010 um 13:27 Uhr)
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#2

AW: DLL neu starten nach beenden

  Alt 20. Okt 2010, 15:54
Meines Wissens geht das nicht. Wenn WinAmp FreeLibrary aufruft gibt es nichts das deine DLL dagegen machen kann. Aber du kannst durchaus experimentieren. Der folgende Code erlaubt es dir beim Laden bzw. Entladen der DLL code auszuführen (am Ende der DLL einfügen):

Delphi-Quellcode:
procedure DLLEntryPoint(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      Load; // wird ausgeführt beim laden der DLL
    DLL_PROCESS_DETACH:
      Unload; // wird ausgeführt beim entladen der DLL
  end;
end;

begin
  DllProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Die Prozeduren Load und Unload musst du natürlich noch implementieren.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: DLL neu starten nach beenden

  Alt 20. Okt 2010, 18:29
Meines Wissens geht das nicht. Wenn WinAmp FreeLibrary aufruft gibt es nichts das deine DLL dagegen machen kann. Aber du kannst durchaus experimentieren. Der folgende Code erlaubt es dir beim Laden bzw. Entladen der DLL code auszuführen (am Ende der DLL einfügen):

Delphi-Quellcode:
procedure DLLEntryPoint(Reason: Integer);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      Load; // wird ausgeführt beim laden der DLL
    DLL_PROCESS_DETACH:
      Unload; // wird ausgeführt beim entladen der DLL
  end;
end;

begin
  DllProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Die Prozeduren Load und Unload musst du natürlich noch implementieren.
Du weist schon das eine Winamp DLL so ausschaut ?

Delphi-Quellcode:
function winampVisGetHeader: PWinAMPVisHeader; cdecl;
begin
  result := @VisHeader;
end;

exports
  winampVisGetHeader;

begin
Ich wüßte jetzt nicht was du denkst das ich bei Load verwenden könnte.

gruss
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#4

AW: DLL neu starten nach beenden

  Alt 20. Okt 2010, 20:01
Das funktioniert bei jeder DLL, nicht bloss bei WinAmp. Damit kann man einfach code beim laden oder entladen der DLL ausführen. Ich wüsste allerdings nicht wie man das entladen abbrechen könnte. Du könntest vielleicht versuchen beim Unload eine Exception zu werfen, aber ich hab keine Ahnung wie das System bzw. WinAmp darauf reagiert.

Und das mit dem selbst wieder aufrufen... ich glaube nicht das das aus der DLL aus geht - im Gegenteil, die Gefahr besteht, dass sich die DLL rekursiv immer wieder lädt bis dem System die Ressourcen ausgehen (Stackoverflow oder noch schlimmeres).

Aber möglicherweise verstehe ich die Problematik auch nicht ganz. Was genau heisst "Vis mit 3 Modulen"? Ich meine ich kenne Winamp und ich habe auch schon mit den Visualisierungen herumgespielt (als Anwender nicht als Programmierer), aber irgendwie verstehe ich nicht ganz was du versuchst zu erreichen. Das umschalten der Module macht doch WinAmp, warum möchtest du da reinfummeln?
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: DLL neu starten nach beenden

  Alt 20. Okt 2010, 20:26
warum möchtest du da reinfummeln?
Weil Winamp eine möglichkeit zur verfügung stellt wie oben beschrieben
die Module bzw.. Presets vor ,zurück und als Random auszuführen.
Ich denke mal nicht das ich da rumfummel wenn die API von Winamp dafür zur verfügung gestellt wird.

Diese Funktion von Winamp habe ich ja schon in meinem wrapper umgesetzt
jetzt möchte ich natürlich auch mein eigenes Plugin den gegebenheiten anpassen was nur logisch ist.

Ok wenn es nicht machbar ist werde ich die Module wohl zusammenführen müssen und diese innerhalb eines Moduls ausführen.

gruss Emil

Siehe Button unter dem VisWindow im Anhang(Bild)

Geändert von EWeiss ( 9. Jul 2019 um 08:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#6

AW: DLL neu starten nach beenden

  Alt 4. Nov 2010, 03:03
Das funktioniert bei jeder DLL, nicht bloss bei WinAmp. Damit kann man einfach code beim laden oder entladen der DLL ausführen.
Sorry, aber ich muß mich hier nochmal klugscheißerisch betätigen.

Einfach ausführen ist Quark. Der Grund ist, daß in der DllMain grundsätzlich das Loader-Lock gehalten wird. Man kann also gewisse Sachen absolut nicht machen. Manche gehen eventuell gut (auch wenn nicht erlaubt), aber das ("dynamische") Laden einer anderen DLL ist bspw. tabu.

Ich wüsste allerdings nicht wie man das entladen abbrechen könnte.
Kann man nicht. Man kann es aber verhindern. DLLs haben im Speicher einen Referenzzähler. Gut, eigentlich haben sie ein Handle, welches ein darunterliegendes Kernelobjekt hat welches den Zähler hat ... Fällt der auf Null, wird die DLL endgültig entladen. Rein theoretisch könnte Code in deiner DLL einfach auf sich selber nochmal LoadLibrary() aufrufen (nur eben nicht in DllMain) ... damit hast du eine Referenz mehr als Winamp kennt. Entsprechend wird deine DLL nicht entladen werden (wenn wir annehmen, daß Winamp nicht einfach solange FreeLibrary aufruft bis deine DLL wirklich wech ist). Allerdings habe ich es nicht getestet, sondern es basiert auf dem Grundlagenwissen zu DLLs usw. und ich halte es für gangbar ...

Du könntest vielleicht versuchen beim Unload eine Exception zu werfen, aber ich hab keine Ahnung wie das System bzw. WinAmp darauf reagiert.
Scherz? Ganz schlechter, wenn es einer war. Denn Exceptions sind, insofern wir nicht von SEH reden, eine Compilerangelegenheit. Und man mag es kaum glauben, aber Winamp dürfte kaum eine Ahnung von Delphis Exceptions haben. Ja, mir ist bekannt, daß viele Compiler auf Windows SEH als Mechanismus für Sprach-Exceptions benutzen. Aber das berührt das vorgesagte nicht im Geringsten. Ich bin mir sogar relativ sicher, daß Winamp SEH-Exceptions abfängt (weil ich die Option zum Abschalten dieser Funktion gesehen habe), aber das kann auch schiefgehen. Grundsätzlich hat sich ein Plugin an die Regeln des ausführenden Programms zu halten!

Und das mit dem selbst wieder aufrufen... ich glaube nicht das das aus der DLL aus geht - im Gegenteil, die Gefahr besteht, dass sich die DLL rekursiv immer wieder lädt bis dem System die Ressourcen ausgehen (Stackoverflow oder noch schlimmeres).
Unsinn. Siehe oben. Da die DLL in Winamp ist und beim Laden einer weiteren Instanz von sich selbst exakt den selben Speicher belegt den sie ohnehin schon hat, kann man bspw. eine einfache Variable per Interlocked-Funktionen hochzählen lassen und bpsw. ab einem bestimmten Wert, ich sage mal 1 oder 2, nicht mehr LoadLibrary aufrufen.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#7

AW: DLL neu starten nach beenden

  Alt 4. Nov 2010, 14:48
Zitat:
Einfach ausführen ist Quark. Der Grund ist, daß in der DllMain grundsätzlich das Loader-Lock gehalten wird. Man kann also gewisse Sachen absolut nicht machen. Manche gehen eventuell gut (auch wenn nicht erlaubt), aber das ("dynamische") Laden einer anderen DLL ist bspw. tabu.
Da wiederspreche ich auch nicht.

Zitat:
Kann man nicht. Man kann es aber verhindern. DLLs haben im Speicher einen Referenzzähler. Gut, eigentlich haben sie ein Handle, welches ein darunterliegendes Kernelobjekt hat welches den Zähler hat ... Fällt der auf Null, wird die DLL endgültig entladen. Rein theoretisch könnte Code in deiner DLL einfach auf sich selber nochmal LoadLibrary() aufrufen (nur eben nicht in DllMain) ... damit hast du eine Referenz mehr als Winamp kennt. Entsprechend wird deine DLL nicht entladen werden (wenn wir annehmen, daß Winamp nicht einfach solange FreeLibrary aufruft bis deine DLL wirklich wech ist). Allerdings habe ich es nicht getestet, sondern es basiert auf dem Grundlagenwissen zu DLLs usw. und ich halte es für gangbar ...
Ja durchaus denkbar, dass es so funktioniert. Aber die Frage ist wie WinAmp wiederum darauf reagiert wenn eine DLL nicht sauber entladen wird bei einem FreeLibrary. Da kann ich mir allerlei Folgefehler ausmalen...

Zitat:
Scherz? Ganz schlechter, wenn es einer war. Denn Exceptions sind, insofern wir nicht von SEH reden, eine Compilerangelegenheit. Und man mag es kaum glauben, aber Winamp dürfte kaum eine Ahnung von Delphis Exceptions haben. Ja, mir ist bekannt, daß viele Compiler auf Windows SEH als Mechanismus für Sprach-Exceptions benutzen. Aber das berührt das vorgesagte nicht im Geringsten. Ich bin mir sogar relativ sicher, daß Winamp SEH-Exceptions abfängt (weil ich die Option zum Abschalten dieser Funktion gesehen habe), aber das kann auch schiefgehen. Grundsätzlich hat sich ein Plugin an die Regeln des ausführenden Programms zu halten!
Ich habe keine systemnahe Kenntnisse von Exceptions. Ich verwende die Dinger einfach und ich weiss dass das auch über die DLL-Grenze hinweg funktioniert. Wie das mit der Kompatibilität unter den einzelnen Programmiersprachen aussieht weiss ich nicht. Deshalb habe ich ja auch geschrieben, dass er es versuchen soll, wenn ich mir sicher gewsen wäre es funktioniert (oder eben nicht) hätte ich das auch so geschrieben.

Zitat:
Unsinn. Siehe oben. Da die DLL in Winamp ist und beim Laden einer weiteren Instanz von sich selbst exakt den selben Speicher belegt den sie ohnehin schon hat, kann man bspw. eine einfache Variable per Interlocked-Funktionen hochzählen lassen und bpsw. ab einem bestimmten Wert, ich sage mal 1 oder 2, nicht mehr LoadLibrary aufrufen.
Ja und was wenn man eben keine Variable hochzählt? Ich glaube die Auswirkungen auf das System könnten vo der übleren Sorte sein... Deshalb habe ich auch auf die Gefahr aufmerksam machen wollen. Ich sage nicht dass es nicht möglich ist, ich weiss dass man von einer DLL aus andere DLLs dynamisch laden kann (das man das nicht von DLLMain aus mahcen soll/kann sei mal dahingestellt). Aber man sollte auch entsprechend vorsichtig sein...
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#8

AW: DLL neu starten nach beenden

  Alt 4. Nov 2010, 15:30
Ja durchaus denkbar, dass es so funktioniert. Aber die Frage ist wie WinAmp wiederum darauf reagiert wenn eine DLL nicht sauber entladen wird bei einem FreeLibrary. Da kann ich mir allerlei Folgefehler ausmalen...
Okay, dann male mal. Wir halten einfach den Referenzzähler größer als Null. Winamp ruft einfach FreeLibrary auf, was genau sollte da fehlschlagen? ... es setzt doch nur den Zähler um eins runter ...

Ja und was wenn man eben keine Variable hochzählt? Ich glaube die Auswirkungen auf das System könnten vo der übleren Sorte sein... Deshalb habe ich auch auf die Gefahr aufmerksam machen wollen. Ich sage nicht dass es nicht möglich ist, ich weiss dass man von einer DLL aus andere DLLs dynamisch laden kann (das man das nicht von DLLMain aus mahcen soll/kann sei mal dahingestellt). Aber man sollte auch entsprechend vorsichtig sein...
Stimmt. Deshalb sollte man es mit Zähler machen - und threadsicher. Allerdings nehme ich an, daß die exportierten Funktionen selber vielleicht nichtmal so oft aufgerufen werden. Und wenn man da drin LoadLibrary aufruft, muß man auch sehr sehr lange Arbeiten bis der Referenzzähler von 32bit überläuft
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#9

AW: DLL neu starten nach beenden

  Alt 4. Nov 2010, 16:12
Malen ist einfach: Ich kenne das nicht genau bei WinAmp, aber ich habe bei meinem eigen Projekt folgendes festestellt:

Mein Projekt lädt die Plugin-DLLs und ruft dort eine Init-Funktion auf, die mir ein Interface zurückliefert mit dem ich dann auf die DLL-funktinen zugreifen kann. In dieser Init-Funktion werden Klassen registriert, ganz einfach in einer Sortierten StringListe (ist eine Globale Variable - ich weiss dass das nicht toll ist, geht aber nicht anders).

Wenn nun die DLL nicht sauber entladen wird, schlägt das Ausführen der Init-Funktion beim nächsten mal fehl, weil die entsprechenden Klassen schon einmal registriert wurden.

Solche Szenarien sind durchaus auch bei WinAmp oder ähnlichen Problemstellungen denkbar...
  Mit Zitat antworten Zitat
Benutzerbild von Assarbad
Assarbad

Registriert seit: 8. Okt 2010
Ort: Frankfurt am Main
1.234 Beiträge
 
#10

AW: DLL neu starten nach beenden

  Alt 4. Nov 2010, 16:45
Solche Szenarien sind durchaus auch bei WinAmp oder ähnlichen Problemstellungen denkbar...
In der Tat, ein berechtigter Einwand. Statische Variablen sind aber einfach nur eine Form der globalen Variablen, die man ohnehin vermeiden sollte

Aber hast schon recht, so ein Szenario würde ggf. fehlschlagen.
Oliver
"... aber vertrauen Sie uns, die Physik stimmt." (Prof. Harald Lesch)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 03:59 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