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

 
Dmitri Custurov #:
Mi chiedo se sia possibile ottenere un vero puntatore a una funzione. I puntatori ottenuti tramite typedef funzionano perfettamente all'interno del programma mql. Ma purtroppo non sono riuscito a passarli nella dll.

Se conoscete il C++ e l'assemblatore integrato e sapete cosa e come inserire nello stack, e se i termini far e near call sono chiari, potete provare. Non posso garantire che funzionerà, ma è possibile.

 
Dov'è l'errore?
#import "msvcrt.dll"
  int memcpy( const int &dst, const int src, const int cnt );
  int memcpy( const int &dst[], const int &src[], const int cnt );  
#import

void OnStart()
{
  int Array[];
  ArrayResize(Array, 1);
  Array[0] = 123;

  const int Address = msvcrt::memcpy(Array, Array, 0);
  int Value = 0;
  
  msvcrt::memcpy(Value, Address + 0, sizeof(int)); // Schianto.

  Print(Value);
}
 
fxsaber #:
Dov'è l'errore?
#import "msvcrt.dll"
        int memcpy(int &dst, int &src[], int cnt);  
        int memcpy(int &dst[], int &src[], int cnt);  
#import



void OnStart() {
        int Array[];
        ArrayResize(Array, 1);
        Array[0] = 123;
        int Value = 0;
        
        msvcrt::memcpy(Value, Array, sizeof(int));
        Print(Value);   // 123
}
 
Edgar Akhmadeev #:

Il tuo esempio nel codice è molto diverso. Sto cercando di ottenere il valore dall'indirizzo.

C'è un esempio nell'articolo.

#import "kernel32.dll"
  int OpenFileMappingW(int dwDesiredAccess, int bInheritHandle,  string lpName);
  int MapViewOfFile(int hFileMappingObject, int dwDesiredAccess, 
                      int dwFileOffsetHigh, int dwFileOffsetLow, int dwNumberOfBytesToMap);
  int UnmapViewOfFile(int lpBaseAddress);
  int CloseHandle(int hObject);
#import "msvcrt.dll"
  int memcpy(uchar &Destination[], int Source, int Length);
  int memcpy(int Destination, int &Source, int Length);
  int memcpy(int Destination, uchar &Source[], int Length);
#import

#define  FILE_MAP_ALL_ACCESS   0x000F001F

//+------------------------------------------------------------------+
//| Funzione di avvio del programma di script|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- aprire l'oggetto di memoria
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- ottenere il puntatore alla memoria
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- leggere i primi 10 byte dalla memoria
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- scrivere un numero int di 4 byte all'inizio della memoria
  memcpy(view, num, 4);
  //--- chiudere la vista
  UnmapViewOfFile(view); 
  //--- chiudere l'oggetto
  CloseHandle(hmem); 
}
Ho evidenziato i punti in cui è scritto per indirizzo. Tuttavia, anche questo esempio dell'articolo si blocca.
 
fxsaber #:

Il tuo esempio nel codice è molto diverso. Sto cercando di ottenere il valore dall'indirizzo.

C'è un esempio nell'articolo.

Ho evidenziato i punti in cui è scritto per indirizzo. Tuttavia, anche questo esempio dell'articolo causa un arresto anomalo.

Ho capito subito cosa volevate. Sono sicuro che l'indirizzo restituito dalle funzioni WinAPI non può essere utilizzato in MQL5. Ma l'indirizzo viene passato correttamente agli argomenti.

Si può essere assolutamente sicuri scrivendo una semplice DLL che mostri l'indirizzo ricevuto nell'argomento e lo restituisca. E confrontare il risultato in MQL5. Molte persone qui praticano il C.

 
fxsaber #:
Dov'è l'errore?
#import "msvcrt.dll"
ulong memcpy(ulong destination,ulong source,ulong count_bytes);
ulong memcpy(ulong destination,uchar &source[],ulong count_bytes);
ulong memcpy(ulong destination,ulong &source[],ulong count_bytes);
ulong memcpy(uchar &destination[],ulong source,ulong count_bytes);
ulong memcpy(ulong &destination[],ulong source,ulong count_bytes);
ulong memcpy(ulong &destination[],ulong source,ulong count_bytes);
#import

Corretto il tuo:

#import "msvcrt.dll"
  int memcpy(uchar &Destination[], int &Source, 
ulong Length);
  int memcpy(int &Destination, int &Source, ulong Length);
  int memcpy(int &Destination, uchar &Source[], ulong Length);
#import

Dovresti avere una lunghezza di 4 o meno ovunque

Copiare più di 2GB funziona

Ottenere l'indirizzo iniziale di un array:

uchar Source[];
ArrayResize(Source,1024*1024*1024);
ulong Source_pointer=memcpy(Source,0,0); 
 
fxsaber #:

Il tuo esempio nel codice è molto diverso. Sto cercando di ottenere il valore dall'indirizzo.

C'è un esempio nell'articolo.

Ho evidenziato i punti in cui è scritto per indirizzo. Tuttavia, anche questo esempio dell'articolo causa un arresto anomalo.

Certo che lo fa... i prototipi sono in 4 (indirizzo a 32 bit come l'unsigned int), e voi li compilate/eseguite in 5 (ha 64).

Non potete fidarvi di nessuno, se usate WinAPI - scrivete voi stessi i prototipi. O meglio scrivere la propria DLL, lasciare che tiri winapi, e di sopra in mql dà interfacce di livello superiore

 
Aliaksandr Hryshyn #:

La copia di più di 2GB funziona

Ottenere l'indirizzo iniziale dell'array:

Ho perso il punto con l'indirizzo a 64 bit. Ma ho ancora un crash con l'indirizzo corretto. È sicuro che dovrebbe funzionare? Posso vedere un esempio completo del codice fxsaber corretto?

Finora sono ancora della mia opinione: l'indirizzo di WinAPI è incompatibile con MQL.

 
Aliaksandr Hryshyn #:

Riparato il tuo:

Maxim Kuznetsov #:

certo che lo fa... i prototipi sono da 4 (indirizzo a 32 bit come unsigned int) e compilano/eseguono in 5 (ha 64).

Grazie, ora funziona.
#import "msvcrt.dll"
  ulong memcpy( const int &dst, const ulong src, const int cnt );
  ulong memcpy( const int &dst[], const int &src[], const int cnt );  
#import

void OnStart()
{
  int Array[];
  ArrayResize(Array, 1);
  Array[0] = 123;

  const ulong Address = msvcrt::memcpy(Array, Array, 0);
  int Value = 0;
  
  msvcrt::memcpy(Value, Address + 0, sizeof(int)); // Schianto.

  Print(Value);
}
 
fxsaber #:
Grazie, ora funziona.

Anche l'ultimo parametro (che è cnt) è a 64 bit. È size_t

https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy

memcpy, wmemcpy
memcpy, wmemcpy
  • TylerMSFT
  • learn.microsoft.com
Learn more about: memcpy, wmemcpy