![MQL5 - Linguaggio delle strategie di trading integrato nel client terminal MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Ti stai perdendo delle opportunità di trading:
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Registrazione
Accedi
Accetti la politica del sito e le condizioni d’uso
Se non hai un account, registrati
I puntatori a variabili, a funzioni, prendere indirizzi per riferimento sono tutte restrizioni MQL.
Non è nemmeno qualcosa che non è previsto dalla sintassi, è un divieto di gestione della memoria.
Anche il puntatore void* non è un puntatore nel senso usuale del C.
È un oggetto per lavorare con gli oggetti di classe per evitare che vengano copiati.
Lo stesso riferimento & non è una presa di indirizzo, ma uno specificatore per il compilatore per passare un oggetto senza copiarlo nello stack.
Se vuoi scrivere in Syakh, scrivi in Syakh e importa dll, va bene.
Se siete davvero impazienti di imparare e non potete foregn dll, allora importare da dll nativo non è un grande peccato, e il vostro prodotto MQL non perderà valore per questo.
Per non fare confusione, per esempio, si può usare solo un puntatore a 4 byte e importare memcpy per lavorare con la memoria all'interno di un processo terminale.
una specie di classe wrapper:
In questo modo potete manipolare la memoria come volete... Non i soliti C-pointers, ma comunque
Come può essere utile?
Bene, per esempio, potete usare la funzione di importazione GlobalAlloc, in modo da non dover usare variabili globali per trasferire dati tra i moduli.
GlobalAlloc alloca la memoria al processo, che non è associata a un heap o a un virtuale statico interno per il lavoro di un gufo o di un indotto.
Potete metterci dentro array di qualsiasi dimensione e usare memcpy per l'indicizzazione.
Esempio di importazione:
#define HANDLE int
#define LPVOID int
Un esempio di utilizzo:
// civetta N1, prepara il tuo array di tassi
Tassi MqlRates[123];
// qui riempiamo
HANDLE memid = GlobalAlloc(GMEM_MOVEABLE, 123*sizeof(MqlRates));
LPVOID ptr=GlobalLock(memid);
memcpy(ptr,rates[0].time, 123*sizeof(MqlRates)); // qui, per compilare, si dovrebbe prototipare int memcpy(int&,const datetime&,int)
GlobalUnlock(memid);
// inviare un descrittore di memoria
EventChartCustom(CID, MY_SEND_DATA, memid, 0, "");
// gufo 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);
Tassi MqlRates[123];
// ha ottenuto dei tassi
memcpy(rates[0].time,ptr,123*sizeof(MqlRates)); // ecco il prototipo int memcpy(datetime&,const int&,int)
GlobalUnlock(memid);
GlobalFree(memid);
}
}
Questo è tutto... niente tubi, file esterni, importazione di dll avanzate.
Ho solo affrettato un piccolo campione con grandi possibilità, ma la mia mente non conosce limiti.
Sì, per quanto riguarda GlobalAlloc suggerisco ancora di usare GMEM_MOVEABLE, con la memoria lock e anlock, per ottenere un puntatore per un'operazione specifica e restituirlo.
Se usate la memoria globale fissa, a N numero di descrittori aperti può verificarsi la frammentazione...
è quello che vuole il kernel del sistema operativo a seconda del carico.
Buona fortuna, hacker )))
Per non essere vaghi, ad esempio, si può usare solo un puntatore a 4 byte e importare memcpy per lavorare con la memoria all'interno del processo terminale
C'è un vecchio libro di Henry Warren, "Algorithmic tricks for programmers", che è pieno di questi trucchi. Tuttavia, la maggior parte degli esempi non funzionerà in MQL a causa della mancanza di puntatori C++.
Cercherò di trovare qualcosa di divertente.
Un po' più di chiarimento per coloro che sanno più.
In C:
int var = 0; // dichiarare la variabile var
int* ptr = &var; // ottenere il puntatore alla variabile var
int var2 = *ptr; // copiare il valore dal puntatore a var in var2
In MQL:
#import "msvcrt.dll"
uint memcpy(int& destination, const int& source, int cnt); // prototipo di memcpy per ottenere l'indirizzo della variabile destination
uint memcpy(int& destination, uint ptr, int cnt); // il prototipo memcpy da copiare dall'indirizzo ptr
// il compilatore sostituirà uno dei due prototipi per differenza di tipo del secondo argomento
// prendiamo un tipo di puntatore, per esempio uint
#import
int var = 0;
uint ptr = memcpy(var,var,0); // otteniamo un puntatore ptr alla variabile var (qui memcpy non copia nulla ma restituisce l'indirizzo var)
int var2
memcpy(var2, ptr, 4); // copia 4 byte o sizeof(int) dal puntatore ptr alla variabile var2 (il secondo prototipo di memcpy funziona)
Spero che troverete il metodo utile ))
Non troverete la somiglianza del mio esempio in C))) In primo luogo, è MQL, in secondo luogo, bypassando la sintassi dei puntatori C.
Spero che lo troverete utile ))))
persone, non scrivete per il gusto di scrivere qualcosa.
Tutte queste varianti con memcpy sono state masticate diversi anni fa e non sono adatte a questo argomento.
Gente, non scrivete per il gusto di scrivere qualcosa.
Tutte queste opzioni di memcpy sono state masticate anni fa e non sono adatte a questo argomento.
Volevo metterlo nel codice base, ma poi ho cambiato idea:
Utilizzo di MQL5 su Kaggle, compito Riconoscitore di cifre
Gente, non scrivete solo per il gusto di scrivere qualcosa.
Tutte queste opzioni di memcpy sono state masticate per anni e non sono adatte a questo argomento.
Perché è "inappropriato"?
Ho dimenticato dov'era e non sono riuscito a trovarlo...
A proposito, considererei un'impresa salvare un puntatore a un array senza chiamare DLL esterne. Non voglio dover confermare ogni volta che avvio gli indicatori che accetto di importare funzioni dalla DLL.
Perché è "non adatto"?
Ho già dimenticato dov'era e non sono riuscito a trovarlo...
A proposito, considererei un'impresa salvare un puntatore a un array senza coinvolgere DLL esterne. Non voglio dover confermare ogni volta che avvio gli indicatori che accetto di importare funzioni da una DLL
Avvolgete l'array in una classe e potete fare pseudo-puntatori MQL ad esso con new
Alexey, dovresti anche dirmi come avvolgere gli array, emessi dalla funzione OnCalculate(), in una classe - in questo caso non puoi fare a meno di copiare i puntatori.
Al momento, sto solo copiando i dati nel mio class-array, e poi sto tirando un puntatore a questo oggetto. Ma questo otterrebbe qualche copia in più, che, come vedo, aggiunge una "pesantezza" abbastanza evidente con frequenti tick e un gran numero di grafici. Voglio sbarazzarmi di questa copia. Ma, a parte una stampella tramite DLL (standard o autoscritta), non c'è niente che possa suggerire.
In Service Desk, continuano a respingermi dicendo "l'oggetto può essere cancellato". Ma questi sono i loro array! Quando dico che posso creare un oggetto e poi rimuoverlo e il puntatore non sarà più valido - rispondono che "sono io che ne sarò responsabile". Qui c'è una "doppia morale" all'opera.
Non mi interessa la DLL - ma tali indicatori richiedono una conferma costante durante l'esecuzione - che seccatura...