Discussione sull’articolo "Sbarazzarsi delle DLL auto-prodotte"

 

Il nuovo articolo Sbarazzarsi delle DLL auto-prodotte è stato pubblicato:

Se la funzionalità del linguaggio MQL5 non è sufficiente per svolgere le attività, un programmatore MQL5 deve utilizzare strumenti aggiuntivi. Deve passare a un altro linguaggio di programmazione e creare una DLL intermedia. MQL5 ha la possibilità di presentare vari tipi di dati e trasferirli all'API ma, purtroppo, MQL5 non può risolvere il problema relativo all'estrazione dei dati dal puntatore accettato. In questo articolo punteremo tutte le "i" e mostreremo semplici meccanismi di scambio e lavoro con tipi di dati complessi.

Come forse saprai, qualsiasi variabile (comprese le variabili di tipi di dati complessi) ha il suo indirizzo specifico, dal quale tale variabile viene archiviata in memoria. Questo indirizzo è un valore intero di quattro byte (di tipo int) uguale all'indirizzo del primo byte di questa variabile.

E se tutto è ben definito, è possibile lavorare con quest'area di memoria. La libreria del linguaggio C (msvcrt.dll) contiene la funzione memcpy. Il suo scopo è l'elemento mancante, che lega MQL5 e varie librerie API e offre grandi possibilità per un programmatore.


Passiamo alla conoscenza dei nostri antenati

La funzione Memcpy copia il numero specificato di byte da un buffer a un altro e restituisce il puntatore a un buffer del ricevitore.

void *memcpy(void *dst, const void *src, int cnt);
dst - pointer to the receiver buffer
src - pointer to the source buffer
cnt - number of bytes for copying

In altre parole, un'area di memoria con una dimensione di cnt byte a partire dall'indirizzo src viene copiata nell'area di memoria a partire dall'indirizzo dst.

I dati che si trovano all'indirizzo src possono essere di vario tipo. Questo può essere una variabile di byte char, doppio numero di otto byte, array, qualsiasi struttura e qualsiasi volume di memoria. Significa che puoi trasmettere liberamente i dati da un'area all'altra, se conosci indirizzi e dimensioni.


Come funziona

Il diagramma 1 mostra le dimensioni comparative di alcuni tipi di dati.

Dimensioni di vari tipi di dati in MQL5


La funzione Memcpy è necessaria per copiare i dati da un'area di memoria all'altra.
La figura 2 mostra la copia di quattro byte.

Esempio di copia di 4 byte con l'utilizzo di memcpy

Autore: ---

 
Grazie per l'articolo, domanda: quando si usa la funzione memcpy, nell'esempio abbiamo scritto l'indirizzo in int, se il sistema è x64, dobbiamo usare la variabile long? Come possiamo scoprire programmaticamente quale sistema (x64, x86)? Grazie.
 

sulla questione del long - è possibile, ma non è affatto necessario, se si usa int come ricevitore a 4 byte di qualcosa di simile da un array di caratteri. (cioè si passa esattamente con il puntatore &).

come scoprirlo - qui potete http://forum.ixbt.com/topic.cgi?id=26:37968

 
sergeev:

sulla questione del long - è possibile, ma non è affatto necessario, se si usa int come ricevitore a 4 byte di qualcosa di simile da un array di caratteri. (cioè si passa esattamente con il puntatore &).

Come scoprirlo - qui può essere http://forum.ixbt.com/topic.cgi?id=26:37968

Puoi chiarire qualcosa sul tempo di scambio in questa struttura (ad esempio, per 10 numeri di formato Int)?
 
shelandr:
Potete chiarire qualcosa sul tempo di scambio in questa struttura (ad esempio, per 10 numeri di formato Int)?

chiarire la domanda.

Stai chiedendo della velocità di memcpy? Penso che questa sia una domanda creativa legata più al lavoro di una libreria wind che a mql.

 
Articolo molto utile e informativo sul lavoro con le API DLL esterne. Grazie mille.
 

Buon pomeriggio. Nonostante l'articolo sia stato scritto relativamente tempo fa, la questione dello scambio di dati con le dll di libreria è ancora attuale. Io stesso di recente mi sono trovato di fronte alla necessità di implementare una certa funzionalità e ho dovuto scegliere se scrivere una mia dll o cercare di utilizzare ancora le dll di libreria. Ho scelto quest'ultima e naturalmente mi sono trovato di fronte alla difficoltà di trasferire le strutture e di recuperare i dati. Dopo aver letto questo articolo non ho capito bene alcuni punti, che a mio parere sono molto complicati. In questo articolo, quando si trasferisce una struttura a un ambiente esterno, si suggerisce di utilizzare un array come area di memoria allocata in cui la funzione di libreria metterà il risultato e che dobbiamo convertire per il lavoro successivo. Ho pochissima esperienza in questo campo e forse il mio ragionamento sembrerà dilettantesco, ma esprimerò comunque la mia opinione nella speranza che persone intelligenti mi correggano. Consideriamo un semplice esempio citato in un vecchio articolo https://www.mql5.com/it/articles/1543.

Quell'articolo tratta il problema della ricerca di file tramite le dll di libreria. Suggerisce inoltre di passare un puntatore a un array della dimensione desiderata e di estrarre i dati richiesti da questo array.

Che cos'è una struttura? È la stessa sezione di memoria. Proviamo ora a cambiare l'approccio al passaggio delle strutture e al recupero dei dati:

// Dichiara i tipi di dati definiti

#define  DWORD int
#define  TCHAR short // Impostare questo tipo, poiché lavoreremo con unicode
#define  MAX_PATH (260)

// Dichiarare la struttura FILETIME
struct FILETIME {
  DWORD dwLowDateTime;
  DWORD dwHighDateTime; 
};

// Dichiarare la struttura dei dati dei risultati della ricerca
struct _WIN32_FIND_DATA {
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  TCHAR cFileName[MAX_PATH];
  TCHAR cAlternateFileName[14]; 
};

// Dichiarando i tipi di dati, copiamo le strutture di WinAPI senza alcuna modifica.
// Importazione della funzione di libreria
#import "kernel32.dll"
   int  FindFirstFileW(string path, _WIN32_FIND_DATA& answer);
#import 
//+------------------------------------------------------------------+
//| Funzione di inizializzazione dell'esperto|
//+------------------------------------------------------------------+
int OnInit()
  {
// Creare una variabile con il tipo della struttura precedentemente creata 
   _WIN32_FIND_DATA data;
// Chiamare la funzione della libreria, passando un puntatore alla nostra struttura e, di fatto, alla memoria allocata. 
int handle = FindFirstFileW(TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Experts\\*.mq5", data);
   if(handle!=-1)
      {
        // Visualizzare il risultato della ricerca accedendo ai campi della nostra struttura senza ulteriori conversioni 
Print("Nome del file trovato: ", ShortArrayToString(data.cFileName));   
         Print("Nome del file temporaneo trovato: ", ShortArrayToString(data.cAlternateFileName));
         Print("Dimensione del file trovata: ", data.nFileSizeLow); 
      }
//---
   return(INIT_SUCCEEDED);
  }
//+-
Групповые файловые операции
Групповые файловые операции
  • 2008.07.15
  • MetaQuotes Software Corp.
  • www.mql5.com
Иногда требуется проделать одинаковые операции для некоторой группы файлов. Если у вас есть список файлов, входящих в эту группу, то это не проблема. Но если этот список нужно получить самостоятельно, то возникает вопрос: "Каким образом?" В статье предлагается сделать это с помощью функций FindFirstFile() и FindNextFile(), входящих в библиотеку kernel32.dll.
 
Алексей Барбашин: Viene anche suggerito di passare un puntatore a un array della dimensione richiesta e quindi di estrarre i dati richiesti da questo array. Si suggerisce anche di passare un puntatore a un array della dimensione richiesta e quindi di estrarre i dati richiesti da questo array.

Che cos'è in sostanza una struttura? È la stessa sezione di memoria. Ora proviamo a cambiare l'approccio al passaggio delle strutture e al recupero dei dati:

Ho incollato correttamente il vostro codice attraverso l'editor

 
Rashid Umarov:

Ho incollato correttamente il tuo codice attraverso l'editor


Grazie mille! Non ho ancora capito come formattare correttamente il codice qui. (((

 
Алексей Барбашин:

Grazie mille! Non ho ancora capito come codificare correttamente qui. (((


Come inserire il codice.

 
Vladimir Karputov:

Come inserire il codice.


Grazie! Ci darò un'occhiata! )))