MT4 DLL Memory Verschmutzung - Seite 2
Seite 2 von 575 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 41

Thema: MT4 DLL Memory Verschmutzung

  1. #11
    BTW: Haben Sie meinen Thread über das Erstellen von DLLs mit FPCLazarus bereits gesehen?
    https://www.tradingintuitive.com/gen...oning-egy.htmlIch sollte ein Kapitel hinzufügen, das sich mit globalen Variablen befasst.

  2. #12
    In der Regel werden globale Variablen in Ihrer DLL erstellt, sobald die DLL geladen wird (erster Aufruf der DLL). und von ALLEN Zugriff geändert. Lokale Variablen innerhalb jeder Funktion werden zugewiesen, wenn die Funktion aufgerufen wird, und Zeiger auf sie werden auf dem Stack gespeichert. Auf sie wird nur von dem Funktionsaufruf, der sie erstellt hat, zugegriffen. Sie werden beim Beenden der Funktion gelöscht. Das Problem, das Sie haben, ist ein Multi-Threading-Problem EG: - E1 und E2 sind 2 EAs, die jeweils in einem anderen Thread laufen. D1 Ihre DLL F1 Ihre DLL-Funktion Eingefügter Code/Ihr DLL-Code/Global Var int x; void F1 (); {int y;/local var x = 1000; während (xgt; 0) {y = 2000; während (ygt; 0) {y--;} x--; }} Wenn es läuft, könnte und wird folgendes passieren: E1 ruft F1 auf und eine neue 'Temp' var Y wird erstellt. Dann hört es auf, zur Hälfte der Funktion zu laufen, da das Betriebssystem angibt, dass die Timeslice abgelaufen ist. Alles funktioniert gut. Wenn E2 nicht existierte, gäbe es überhaupt keine Probleme. E2 ruft jetzt F1 auf und eine neue 'Temp' var Y wird erstellt. F1 Setzt sofort x auf 1000 ... Sie haben jetzt den Aufruf von E1 an die Funktion gebrochen, da sich die globale Variable geändert hat. Wenn E1 den Prozessor zurückerhält, wird int x anders sein, als wenn er abgebrochen wurde. Natürlich weiß oder interessiert E1 das nicht. Sie können dieses Problem leicht lösen, ohne OOP. Sie müssen lediglich wissen, dass Sie dieselbe Funktion (en) von mehreren Threads aus aufrufen, um Thread-sicher zu sein. Entweder mit oder ohne OOP müssen Sie eine Möglichkeit haben, jedem EA ein separates int X zuzuordnen. Daher muss eine Init-Funktion bereitgestellt werden, um jedem EA eine separate 'Bank' globaler Variablen zuzuordnen. Im obigen Beispiel könnte dies leicht erreicht werden, indem Int X zu einem Array mit geeigneter Größe gemacht wird und initdeinit-Funktionen bereitgestellt werden, um ein Array-Dimensionselement jedem eindeutigen Aufrufer für die init-Funktion zuzuordnen. Z.B. E1 int myID = DLLinit ('GBPJPY');/gibt 1 zurück F1 (myID);/Jetzt kann F1 MyID verwenden, um auf das korrekte X var im globalen Array zu verweisen. E2 int myID = DLLinit ('EURUSD');/Returns 1 OOP ist oft eine weitaus elegantere Methode, dieses Problem zu beheben, funktioniert jedoch nur, wenn Sie das Problem verstehen und es dann richtig codieren. Mit OOP möchten Sie ein neues Objekt erstellen (eines für jeden EA), wenn Sie eine DLL-Init-Funktion aufrufen. Dies funktioniert nur, wenn Sie in jedem neuen Objekt einen separaten Satz von 'globalen' Variablen einkapseln.

  3. #13
    7bit: Ich habe den Code geändert, um diese globalen Variablen nicht zu haben. Ich hatte sie erst bemerkt, als ich den Code eingefügt hatte. Auch mit Ihrer Bestätigung, dass sie zwischen den Aufrufen bestehen bleiben, ist es vollkommen sinnvoll, warum er das tat, was er war . Ich werde Sie wissen lassen, wie ich mit Demo-Tests davon weiterkomme. Ich werde jetzt einen Blick auf Ihren Artikel werfen, ich habe ihn vielleicht gelesen, Sie haben in diesen Tagen so viel gelesen! Noch einmal vielen Dank

  4. #14
    Rangebound: Vielen Dank für Ihren Beitrag, ich kann sehen, dass das Problem falsch war, dass ich davon ausging, dass jede Last eines EAs eine separate Instanz der DLL laden würde, getrennt von anderen Aufrufen, die möglicherweise vorkommen. Stimme deinem Beispiel vollkommen zu. Witzigerweise wusste ich, dass dies mir tatsächlich eine Lösung für ein anderes Problem gab, das ich hatte, die Antwort war die ganze Zeit dort. Danke für Ihre Hilfe

  5. #15
    Ich möchte mich auch bedanken! zu 7bit und für ihre Unterstützung hier rangebound. Es war sehr hilfreich. Ich verwende Delphi 2009 (Object Pascal), um meine DLLs zu schreiben. Mit den Ratschlägen in diesem Thread und auch hier habe ich alle Abstürze beseitigt, indem alle globalen Variablen in eine Klasse verschoben und ein Zeiger auf das Objekt zwischen MT4 und der DLL übergeben wurde. Dies löste alle Speicherkollisionen. Es scheint jedoch immer noch etwas zu geben, das ich nicht verstehe. Um zu vermeiden, dass ALLE Abstürze ausgeführt werden, musste ich eine TCriticalSection verwenden, um sicherzustellen, dass jeweils nur ein Diagramm auf die DLL zugreift. Zum Beispiel: Eingefügter Code/Delphi (Object Pascal) DLL-Code: var csTick: TCriticalSection; Funktion DLLGet: Boolean; begin csTick.Enter; Ergebnis: = wahr; Ende; Prozedur DLLFree; begin csTick.Leave; Ende; Initialisierung csTick: = TCriticalSection.Create; Finalisierung csTick.Free; Eingefügter Code/EA-Code: #import MyLogic.dll bool DLLGet (); void DLLFree (); #import int init () {DLLGet (); int iPointer = DLLGetNewObject (Symbol ()); ... andere Initialisierung ... DLLFree (); return (0); } int start () {statisch int iPrevOrderCount = 0; DLLGet (); ... mehrere DLL-Funktionsaufrufe ... DLLFree (); return (0); } Ich habe keine globalen Variablen in der DLL. Alles (außer das TCriticalSection-Objekt) wird in die Klasse eingeschlossen und die Klassenreferenz wird mit jedem Funktionsaufruf an die DLL übergeben. Aber ich bekomme immer noch eine Art KollisionKorruption, weil ich den Thread-Semaphor (TCriticalSection) verwenden muss, damit er richtig funktioniert. Hier ist der Grund, warum ich das alles anspreche. Es gibt noch ein kleines Problem: Wenn deinit () für ein Diagramm aufgerufen wird, bricht MT4 sofort die start () - Funktion ab, was manchmal bedeutet, dass DLLFree () nicht aufgerufen wird und alle anderen Diagramme aus der DLL gesperrt sind. Zusammenfassend ist meine Frage: Warum muss ich das TCriticalSection-Semaphor verwenden? Wenn alles in einer Klasse ist, welche Kollisionen könnte es dann geben? Vielen Dank!

  6. #16
    Mein Fehler
    . Ich habe in einer enthaltenen Einheit eine globale Variable gefunden. Ich habe diese var entfernt und alles ist jetzt in Ordnung - ohne die Semaphore! Nochmals vielen Dank für Ihre Hilfe.

  7. #17
    Sie sollten keine kritischen Abschnitte für die meisten DLLs verwenden müssen. Dies weist auf ein anderes zugrundeliegendes Codierungsproblem hin, das eines von vielen Dingen sein kann. Das Beste, was Sie tun können, ist ... Schneiden Sie den Code aus Ihrer DLL aus, bis Sie die grundlegendste DLL haben, die noch abstürzt. Dann poste die Quelle hier und ich werde einen Blick darauf werfen. Bedenken Sie, dass Sie nicht angeben, wann ein Absturz auftritt ... Wenn Sie diese Route nicht begehen möchten, sind meine besten Vermutungen: 1) Wenn Ihr EA ein DeinitInit ausführt, versucht Ihre DLL möglicherweise, ein zweites Objekt für die das gleiche Währungspaar. Haben Sie eine Falle programmiert, um das Kopieren zu stoppen? Gehen Sie nicht davon aus, dass Ihre DLL garantiert einen DeInit-Aufruf erhält. Sie müssen nach Duplizierungen derselben Währungsinitialisierungen suchen. 2) Speichert Ihr DLL die Zeiger auf diese Objekte und verwaltet sie deren Zerstörung?

  8. #18
    Danke, Rangebound! Alles funktioniert jetzt einwandfrei, ohne Abstürze oder Speicherlecks, aber Ihr Beitrag wirft ein paar Fragen auf:
    Zitat Zitat von ;
    1) Wenn Ihr EA ein DeinitInit ausführt, kann Ihr DLL versuchen, ein zweites Objekt für dasselbe Währungspaar zu erstellen. Haben Sie eine Falle programmiert, um das Kopieren zu stoppen? Gehen Sie nicht davon aus, dass Ihre DLL garantiert einen DeInit-Aufruf erhält. Sie müssen nach Duplizierungen derselben Währungsinitialisierungen suchen.
    So wie ich es geschrieben habe, wenn deinit () nicht aufgerufen wird, wird das Objekt nicht freigegeben. Aber abgesehen von dem Speicherverlust, der nicht zum Absturz führen sollte, weil das zweite Objekt eine neue Speicherposition hat, richtig?
    Zitat Zitat von ;
    2) Speichert Ihr DLL die Zeiger auf diese Objekte und verwaltet sie deren Zerstörung?
    Normalerweise würde ich eine TThreadList (eine Thread-blockierende Liste von Zeigern) in der DLL verwenden, um so etwas zu tun - gibt es einen anderen Weg? Mit anderen Worten, wie sollte ich die Zeiger in der DLL speichern, ohne eine globale Variable oder einen blockierenden Mechanismus zu verwenden? Das ist sehr hilfreich - danke für Ihre Beiträge.

  9. #19

    Zitat Zitat von ;
    Speichern Sie die Zeiger überhaupt nicht in der DLL. Konvertieren Sie sie in 32-Bit-Ganzzahlen, speichern Sie sie im EA, behandeln Sie sie wie Ressource-Handles und übergeben Sie sie als Parameter an Wrapper-Funktionen in der DLL (die sie dann zurückwerfen, dereferenzieren und die tatsächliche Methode aufrufen der Objektinstanz). Ich mache das in meiner Python-Bindung. Alle Python-Objekte in der python26.dll sind eigentlich Zeiger, aber ich kann sie leicht als Ganzzahlen behandeln, die vom mql-Code verwendet werden. Alle meine Python-API-Wrapper-Funktionen, die einen Zeiger auf ein Python-Objekt benötigen, akzeptieren einfach eine Ganzzahl. Für den MQL-Code sind alle Python-Objekte nur Ganzzahl-Handles.

  10. #20

    Zitat Zitat von ;
    Speichern Sie die Zeiger überhaupt nicht in der DLL. Konvertieren Sie sie in 32-Bit-Ganzzahlen, speichern Sie sie im EA, behandeln Sie sie wie Ressource-Handles und übergeben Sie sie als Parameter an Wrapper-Funktionen in der DLL (die sie dann zurückwerfen, dereferenzieren und die tatsächliche Methode aufrufen der Objektinstanz). Ich mache das in meiner Python-Bindung. Alle Python-Objekte in der python26.dll sind eigentlich Zeiger, aber ich kann sie leicht als Ganzzahlen behandeln, die vom mql-Code verwendet werden. Alle meine Python-API-Wrapperfunktionen, die einen Zeiger auf einen Python benötigen ...

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  
Die tradingintuitive Webseite verwendet Cookies
Wir nutzen Cookies, um Ihnen das Webseitenerlebnis bestmöglich anbieten zu können. Durch weitere Nutzung der Webseite erlauben Sie die Nutzung von Cookies. Für weitere Details und wie Sie ggf. diese Einstellungen verändern können, lesen Sie bitte unsere Datenschutzbestimmung. Lesen Sie mehr