Sie verpassen Handelsmöglichkeiten:
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Registrierung
Einloggen
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Zeiger auf Variablen, auf Funktionen und die Übernahme von Adressen durch Verweise sind allesamt MQL-Einschränkungen.
Es handelt sich nicht einmal um etwas, das in der Syntax nicht vorgesehen ist, sondern um ein Verbot der Speicherbehandlung.
Auch der void*-Zeiger ist kein Zeiger im üblichen C-artigen Sinne.
Es ist ein Objekt, das mit Klassenobjekten arbeitet, um zu verhindern, dass sie kopiert werden.
Die gleiche Referenz & ist keine Adressübernahme, sondern eine Angabe für den Compiler, um ein Objekt zu übergeben, ohne es in den Stack zu kopieren.
Wenn Sie in Syakh schreiben wollen, schreiben Sie in Syakh und importieren Sie dll, das ist in Ordnung.
Wenn es Ihnen wirklich in den Fingern juckt und Sie die dll nicht vorhersehen können, dann ist der Import aus der nativen dll keine große Sünde, und Ihr MQL-Produkt wird dadurch nicht an Wert verlieren.
Um nicht zu viel Aufhebens zu machen, können Sie zum Beispiel nur einen 4-Byte-Zeiger verwenden und memcpy importieren, um mit dem Speicher innerhalb eines Terminalprozesses zu arbeiten.
eine Art von Wrapper-Klasse:
Auf diese Weise können Sie den Speicher nach Belieben manipulieren... Nicht die üblichen C-Zeiger, aber dennoch
Wie kann sie nützlich sein?
Sie können zum Beispiel die Importfunktion GlobalAlloc verwenden, so dass Sie keine globalen Variablen verwenden müssen, um Daten zwischen Modulen zu übertragen.
GlobalAlloc weist dem Prozess Speicher zu, der nicht mit einem Heap oder internen statischen virtuellen für die Arbeit einer Eule oder eines induzierten verbunden ist.
Sie können Arrays beliebiger Größe darin platzieren und memcpy zur Indizierung verwenden.
Beispiel importieren:
#define HANDLE int
#define LPVOID int
Ein Beispiel für die Verwendung:
// owl N1, bereiten Sie Ihr Array von Raten vor
MqlRates rates[123];
// hier füllen wir
HANDLE memid = GlobalAlloc(GMEM_MOVEABLE, 123*sizeof(MqlRates));
LPVOID ptr=GlobalLock(memid);
memcpy(ptr,rates[0].time, 123*sizeof(MqlRates)); // hier sollte man, um zu kompilieren, den Prototyp int memcpy(int&,const datetime&,int)
GlobalUnlock(memid);
// Senden eines Speicherdeskriptors
EventChartCustom(CID, MY_SEND_DATA, memid, 0, "");
// Eule N2
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if( id == CHARTEVENT_CUSTOM+MY_SEND_DATA )
{
LPVOID ptr = GlobalLock((HANDLE)lparam);
MqlRates rates[123];
// Preise erhalten
memcpy(rates[0].time,ptr,123*sizeof(MqlRates)); // hier ist der Prototyp int memcpy(datetime&,const int&,int)
GlobalUnlock(memid);
GlobalFree(memid);
}
}
Das ist alles... keine Pipes, externe Dateien, Import von übrig gebliebenen DLLs.
Ich habe nur eine kleine Probe mit großen Möglichkeiten überstürzt, aber mein Geist kennt keine Grenzen.
Ja, in Bezug auf GlobalAlloc schlage ich immer noch vor, GMEM_MOVEABLE zu verwenden, mit lock und anlock Speicher, um einen Zeiger für eine bestimmte Operation zu erhalten, geben Sie es zurück.
Wenn Sie festen globalen Speicher verwenden, kann es bei einer Anzahl von N offenen Deskriptoren zu einer Fragmentierung kommen...
was immer der Betriebssystem-Kernel je nach Belastung wünscht.
Viel Glück, Hacker )))
Um nicht zu vage zu sein, können Sie zum Beispiel nur einen 4-Byte-Zeiger verwenden und memcpy importieren, um mit dem Speicher innerhalb des Terminalprozesses zu arbeiten
Es gibt ein altes Buch von Henry Warren, "Algorithmische Tricks für Programmierer", das voll von solchen Tricks ist. Die meisten Beispiele funktionieren jedoch nicht in MQL, weil es keine C++-Zeiger gibt.
Ich werde versuchen, etwas Lustiges zu finden.
Ein wenig mehr Klarheit für diejenigen, die wissen, plus.
In C:
int var = 0; // deklariere Variable var
int* ptr = &var; // erhalte Zeiger auf Variable var
int var2 = *ptr; // kopiere Wert durch Zeiger auf var in var2
In MQL:
#import "msvcrt.dll"
uint memcpy(int& destination, const int& source, int cnt); // Prototyp von memcpy, um die Adresse der Variablen destination zu erhalten
uint memcpy(int& destination, uint ptr, int cnt); // der memcpy-Prototyp zum Kopieren von der Adresse ptr
// der Compiler ersetzt einen der beiden Prototypen durch den Typunterschied des zweiten Arguments
// Nehmen wir einen Zeigertyp, z.B. uint
#import
int var = 0;
uint ptr = memcpy(var,var,0); // erhält einen Zeiger ptr auf die Variable var (hier kopiert memcpy nichts, sondern liefert die Adresse var)
int var2
memcpy(var2, ptr, 4); // kopiere 4 Bytes oder sizeof(int) vom Zeiger ptr in die Variable var2 (der zweite Prototyp von memcpy funktioniert)
Ich hoffe, Sie finden die Methode nützlich )))
Sie werden die Ähnlichkeit meines Beispiels in C))) nicht finden. Erstens ist es MQL, zweitens die Umgehung der C-Zeiger-Syntax.
Ich hoffe, Sie finden es nützlich ))))
Leute, schreibt nicht nur um des Schreibens willen.
Alle diese Varianten mit memcpy sind schon vor einigen Jahren durchgekaut worden und eignen sich nicht für dieses Thema.
Leute, schreibt nicht um des Schreibens willen.
Alle diese memcpy-Optionen wurden vor Jahren wiedergekäut und sind für dieses Thema nicht geeignet.
Ich wollte es in die Codebasis aufnehmen, aber dann habe ich meine Meinung geändert:
Verwendung von MQL5 bei Kaggle, Ziffernerkennungsaufgabe
Leute, schreibt nicht nur um des Schreibens willen.
Alle diese memcpy-Optionen sind seit Jahren durchgekaut worden und eignen sich nicht für dieses Thema.
Warum ist es "unangemessen"?
Ich habe schon vergessen, wo es war und konnte es nicht mehr finden...
Übrigens, einen Zeiger auf ein Array zu speichern, ohne externe DLLs aufzurufen, würde ich als Kunststück bezeichnen. Ich möchte nicht jedes Mal, wenn ich Indikatoren starte, bestätigen müssen, dass ich mit dem Import von Funktionen aus der DLL einverstanden bin.
Warum ist sie "nicht geeignet"?
Ich habe schon vergessen, wo es war und konnte es nicht mehr finden...
Übrigens würde ich es als Kunststück betrachten, einen Zeiger auf ein Array zu speichern, ohne externe DLLs einzubeziehen. Ich möchte nicht jedes Mal, wenn ich Indikatoren starte, bestätigen müssen, dass ich mit dem Import von Funktionen aus einer DLL einverstanden bin.
Wickeln Sie das Array in eine Klasse ein und Sie können MQL-Pseudo-Zeiger darauf mit new
Alexey, du solltest mir auch sagen, wie man Arrays, die von der Funktion OnCalculate() ausgegeben werden, in eine Klasse einpackt - in diesem Fall geht es nicht ohne das Kopieren von Zeigern.
Im Moment kopiere ich nur Daten in mein Klassenarray, und dann ziehe ich einen Zeiger auf dieses Objekt. Aber das würde zu zusätzlichen Kopiervorgängen führen, die, wie ich sehe, bei häufigen Ticks und einer großen Anzahl von Diagrammen zu einer spürbaren "Schwerfälligkeit" führen. Ich möchte dieses Kopieren loswerden. Aber außer einer Krücke über eine DLL (Standard oder selbst geschrieben), gibt es nichts, was ich vorschlagen kann.
Im Service Desk werde ich immer wieder mit der Aussage "das Objekt kann gelöscht werden" zurückgewiesen. Aber das sind ihre eigenen Arrays! Wenn ich sage, dass ich ein Objekt erstellen und es dann entfernen kann und der Zeiger ungültig wird, antworten sie, dass "ich dafür verantwortlich sein werde". Hier ist eine "doppelte Moral" am Werk.
Ich kümmere mich nicht um die DLL - aber solche Indikatoren erfordern eine ständige Bestätigung, wenn sie laufen - was für ein Ärgernis...