Seltsames String-Verhalten
Ergebnis 1 bis 8 von 8

Thema: Seltsames String-Verhalten

  1. #1
    OK Leute Danke für die Hilfe es scheint, dass die MQL-Dokumente etwas unklar sind. Ich konzentriere mich jetzt darauf, neue Strings aus der DLL (als Funktionsaufruf in Delphi) zurückzugeben, anstatt existierende zu ändern. Und ich werde versuchen, die Verwendung von Strings in Zukunft zu begrenzen, wie es 7Bit vorschlägt

  2. #2
    Wie 7Bit besagt, dass Sie Speicher manipulieren, den Sie (DLL) nicht zugewiesen haben, und Sie nicht wissen, wie MQL Speicher mit diesem String zuordnet oder wie er seine dynamische Größe speichert (Länge) MQL String tstr; tstr = DLLreturnNullString (); Das funktioniert, weil MQL einen Zeiger auf eine Term-Zeichenfolge erhält (für die der DLL Speicher reserviert). MQL behandelt dann die Zuweisung seines eigenen Arbeitsspeichers und seiner internen ZuweisungslistenStringgrößenliste und kopiert die Daten in diesen neuen MQL-Speicher. Alles gut, weil Sie MQL eine eigene Kopie der Zeichenfolge erstellen lassen. MQL Zeichenfolge tstr; DLLchangethisString (tstr); Dies ist aus mehreren Gründen gefährlich: A) Sie wissen nicht, wieviel Speicher (falls vorhanden) MQL dem Zeiger zugewiesen hat, den Ihre DLL empfängt. B) Wenn Sie die Zeichenkette ändern, dann weiß MQL nichts darüber, und wenn Sie die Länge der Zeichenkette ändern, dann hat MQL sein eigenes ”Wissen” über die Länge der Zeichenkette C nicht aktualisiert, wenn Sie versuchen, die Zeichenkette zu ändern oder zu lesen über Schritt den Speicher, den MQL für sie zugeteilt dann haben Sie einen Schutzfehler D) Meiner Erfahrung nach, während MQL Strings bis zu 64KB Größe erlaubt Im sicher bin der Speicher nicht immer als ein zusammenhängender Speicherblock zugeordnet. Wenn Sie diese Route beibehalten (und nicht raten), ist der beste Weg MQL int len; String tstr =;/pad bis zu 255 Zeichen zur Definitionszeit, so dass Speicher zugewiesen wird DLLchangethisString (len, tstr); Drucken (StringSubstr (tstr, 0, len)); Auf diese Weise gibt Ihre DLL die neue Länge der Zeichenfolge zurück, sodass Sie zumindest etwas über die neue Länge wissen. Ich habe einen C-Header gesehen, der die MQL-String-Struktur detailliert beschreibt (aber nie benutzt hat), was darauf hinweist, dass die String-Länge in einem INT (4 Bytes) vor dem Beginn des Strings gespeichert ist. In Ihrer DLL könnten Sie also versuchen, den von MQL gelieferten String Pointer (um 4 Bytes) zu dekrementieren und eine Integer an diesen Speicherort zu schreiben, um die neue Länge zu definieren. JEDOCH habe ich es nie probiertweiß nicht, ob das richtig ist und ich würde es nicht empfehlen Das liegt daran, dass Sie mit MQLs Wissen darüber, was es mit diesem String gemacht hat, herumhantieren, wenn Sie seine Länge von 255 auf 10 ändern, dann könnte MQL den Speicher verlieren, den Ihre DLL unwissend gemacht hat.

  3. #3

    Zitat Zitat von ;
    Also, was ist der konventionelle Weg, um mehrere String-Werte zurück aus einer DLL (Ich benutze Delphi7 übrigens) Ich akzeptiere Ich kann eine Arbeit umgehen, wie Sie mit Ganzzahlen beschreiben, aber ich hatte verstanden, dass Strings als Zeiger auf den Speicher übergeben werden konnte Block sehen
    http://docs.mql4.com/basis/variables/extfunctionsVielen Dank
    Es gibt etwas geschrieben über Zeiger auf Speicherblöcke und etwas, das wie Pascal-Strings klingt, macht keinen Sinn (vielleicht macht es mehr Sinn im russischen Original) und sie sprechen nicht darüber, den String für die spätere Verwendung durch das mql4-Skript zu modifizieren . Was ich aus eigener Erfahrung sagen kann, ist, dass Strings, die an die DLL übergeben werden, einfach Zeiger auf terminierte Strings sind. In Pascal würden Sie dafür einen PChar-Typ verwenden. Ich hatte nur eine Instanz, wo ich jemals die Notwendigkeit verspürte, eine Zeichenkette von der DLL zum Skript zurückzugeben, und das war, als ich meine Pythonbindung schrieb. Die Funktion, die den Wert eines Python-String-Objekts an das aufrufende mql4-Skript zurückgibt, sieht folgendermaßen aus: Eingefügte Code-Funktion PyGetString (Element: PPyObject): # 91; color = Rot # 93; PChar # 91;color # 93 ;; stdcall; var gs: TGILState; Beginne gs: = PyGILState_Ensure (); PyGetString: = PyString_AsString (Element); PyGILState_Release (gs); Ende; (Den vollständigen Quellcode (LazarusFPC) als angehängte RAR-Datei finden Sie am Ende dieser Site:
    http://sites.google.com/site/prof/me...on-integration) Das obige gibt einen Zeiger auf den String zurück (erstellt von der Python-DLL), indem einfach der Rückgabewert der Funktion verwendet wird. MT4 kopiert die Zeichenfolge vom zurückgegebenen Zeiger sofort in den eigenen Speicher. Wenn ich den konventionellen Weg empfahl, bezog ich mich auf den konventionellen Weg zur Lösung des Problems, nicht auf die konventionelle Art, Saiten zurückzugeben. Die herkömmliche Lösung des Problems (was auch immer es sein mag) würde höchstwahrscheinlich keine Verwendung von Strings enthalten, die an das Skript zurückgegeben werden. Deshalb hier nochmal die Frage: Was versuchst du zu machen?

  4. #4

    Zitat Zitat von ;
    Was versuchst du zu tun, das kann nicht konventionell gemacht werden?
    Also, was ist der konventionelle Weg, um mehrere String-Werte zurück aus einer DLL (Ich benutze Delphi7 übrigens) Ich akzeptiere Ich kann eine Arbeit umgehen, wie Sie mit Ganzzahlen beschreiben, aber ich hatte verstanden, dass Strings als Zeiger auf den Speicher übergeben werden konnte Block sehen
    http://docs.mql4.com/basis/variables/extfunctionsVielen Dank

  5. #5

    Zitat Zitat von ;
    Wenn ich es richtig verstanden habe, kopiere ich die Daten in den vom Skript zugewiesenen Speicher
    Sie können nicht sicher sein, wie Metatrader Strings intern behandelt. Möglicherweise empfängt Ihre DLL nur einen Zeiger auf eine C-kompatible (-terminierte) Kopie der Zeichenfolge, die nach dem Aufruf verworfen wird, und intern speichert sie Zeichenfolgen auf eine völlig andere Art und Weise. Vielleicht ist es der Heap-Manager, der die Referenzobjekte verwaltet und Klone für bestimmte Operationen erstellt, vielleicht intern sind sie Pascal-Strings und nicht C-Strings, oder sie benutzten eine ausgefeilte String-Bibliothek, die komplett mit Unicode oder ähnlichem arbeitet. Wer weiß? Es ist nirgends dokumentiert! Sie versuchen, Metatraders eigene undokumentierte Datenstrukturen über eine undokumentierte Schnittstelle direkt zu manipulieren! Was versuchst du zu tun, das kann nicht konventionell gemacht werden?
    Zitat Zitat von ;
    Ein bisschen verwirrend, ich stimme zu, aber ich verwende das Array Levels, um die tatsächlichen Werte zu übergeben. Die Strings sind für einen anderen Zweck insgesamt
    Kann es nicht alles in ganzzahligen Werten codiert werden? Wenn diese Strings eine endliche Anzahl von Befehlen oder Zuständen darstellen, dann codiere sie einfach als Ganzzahlen. Definieren Sie eine Konstante für jeden möglichen Befehl oder Modus oder Status zur besseren Lesbarkeit, genau wie im Metatrader: (OP_BUY, OP_SELL, MODE_FOO, MODE_BAR, etc.). Das Verwenden von Strings für solche Dinge sieht sehr seltsam aus. Es gibt einen Grund, warum dies nie anderswo gemacht wird. (außer PHP vielleicht, weil die PHP-Kiddies nicht wissen, was eine Konstante ist)

  6. #6

    Zitat Zitat von ;
    Warum erzählst du uns nicht, was in der nach dem Aufruf geöffneten Variable enthalten ist?
    Im Grunde kann es alles sein, zB eine Folge von 4 Zeichen abcd
    Zitat Zitat von ;
    Sind Sie sicher, dass Sie Zeichenfolgen als Zeiger übergeben können (wie Sie es offensichtlich tun), sie in Ihrer DLL ändern lassen und dann noch in MT4 arbeiten, ohne eine Zugriffsverletzung zu erzeugen?
    Nun, ich habe keine AVs. und alles funktioniert gut, vorausgesetzt, ich erlaube genügend Speicher für die Variablen in meinem Skript (dh deshalb richte ich zuerst die Standardwerte ein) mindestens so weit wie die zurückgegebenen Werte betroffen sind. Es ist die Vergleichsfunktion, die fehlschlägt in meinen Annahmen und würde gerne wissen, ob ich auf diese Weise Zeichenfolgen übergeben kann, wie ich mit doubles und Integers (als Arrays) jedoch
    Zitat Zitat von ;
    Ordnen Sie der neuen Zeichenfolge in Ihrer DLL neuen Speicher zu?
    Wenn ich es richtig verstanden habe, kopiere ich die Daten in den vom Skript zugewiesenen Speicher
    Zitat Zitat von ;
    Warum verwenden Sie nicht stattdessen string, um den neuen Zeiger dann zurückgeben zu können? Wer ist verantwortlich für die Freigabe dieses neu zugewiesenen Speichers?
    Die Verwendung von string gibt einen AV und, wie ich verstehe, wird der gesamte Speicher vom Skript verwaltet
    Zitat Zitat von ;
    Und die wichtigste Frage: Warum in aller Welt machst du das überhaupt mit Saiten?
    Ein bisschen verwirrend, ich stimme zu, aber ich verwende das Array Levels, um die tatsächlichen Werte zu übergeben. Die Strings sind für einen anderen Zweck insgesamt

  7. #7

    Zitat Zitat von ;
    if (open! = open) Drucken (NE); sonst Drucken (EQ); der Test schlägt fehl und ich bekomme EQ gedruckt
    Warum erzählst du uns nicht, was in der nach dem Aufruf geöffneten Variable enthalten ist? Sind Sie sicher, dass Sie Zeichenfolgen als Zeiger übergeben können (wie Sie es offensichtlich tun), sie in Ihrer DLL ändern lassen und dann noch in MT4 arbeiten, ohne eine Zugriffsverletzung zu erzeugen? Ordnen Sie der neuen Zeichenfolge in Ihrer DLL neuen Speicher zu? Warum verwenden Sie nicht stattdessen string, um den neuen Zeiger dann zurückgeben zu können? Wer ist verantwortlich für die Freigabe dieses neu zugewiesenen Speichers? Und die wichtigste Frage: Warum in aller Welt machst du das überhaupt mit Saiten?

  8. #8
    Hat jemand auf folgendes gestoßen

    Ich habe ein Skript mit den folgenden Deklarationen

    Zeichenkettensymbol = XXXXXX;
    Schnur offen = offen; Fadenstopp = Stopp; String takeP = nehmen;
    doppelte Ebenen [3];
    int Daten [1];

    Ich rufe dann eine wie folgt deklarierte DLL auf

    void GetParmQuery (Zeichenkettensymbol, Zeichenkette offen, Zeichenkette stop, Zeichenkette takeP,
    doppelte Ebenen [], int Daten []);

    Die von der DLL zurückgegebenen Werte sind wie erwartet, dh die Standardwerte für symbol, open, stop und takeP wurden geändert. Wenn ich dann den folgenden Test mache

    if (offen! = offen)
    Druck (NE);
    sonst
    Druck (EQ);

    der Test schlägt fehl und ich bekomme EQ gedruckt

    Irgendwelche Ideen, was passiert und kann ohne eine unordentliche Arbeit repariert werden

    Vielen Dank

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