Discusión sobre el artículo "Cómo deshacerse del lastre de las DLL caseras" - página 3

 
Dmitri Custurov #:
Me pregunto si es posible obtener un puntero real a una función. Los punteros obtenidos usando typedef funcionan perfectamente bien dentro del programa mql. Pero desgraciadamente no he conseguido pasarlos a la dll.

Si conoces C++ + ensamblador incorporado y sabes qué y cómo poner en la pila, y los términos llamada lejana y cercana están claros, puedes intentarlo. No puedo garantizar que funcione, pero es posible.

 
¿Dónde está el error?
#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)); // Crash.

  Print(Value);
}
 
fxsaber #:
¿Dónde está el error?
#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 #:

Su ejemplo en el código es bastante diferente. Estoy tratando de obtener el valor de la dirección.

Hay un ejemplo en el artículo.

#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

//+------------------------------------------------------------------+
//| Función de inicio del programa de script|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- abrir el objeto de memoria
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- obtener puntero de memoria
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- lee los 10 primeros bytes de la memoria
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- escribe un número int de 4 bytes al principio de la memoria
  memcpy(view, num, 4);
  //--- cerrar la vista
  UnmapViewOfFile(view); 
  //--- cerrar el objeto
  CloseHandle(hmem); 
}
He resaltado los lugares donde se escribe por dirección. Sin embargo, este ejemplo del artículo también se bloquea.
 
fxsaber #:

Su ejemplo en el código es bastante diferente. Estoy tratando de obtener el valor de la dirección.

Hay un ejemplo en el artículo.

He resaltado los lugares donde se escribe por dirección. Sin embargo, este ejemplo del artículo también provoca un fallo.

Entendí inmediatamente lo que querías. Estoy seguro de que la dirección devuelta por las funciones WinAPI no se puede utilizar en MQL5. Pero la dirección se pasa a los argumentos correctamente.

Puedes estar absolutamente seguro escribiendo una simple DLL que muestre la direccion recibida en el argumento y la devuelva. Y comparar el resultado en MQL5. Mucha gente aqui practica C.

 
fxsaber #:
¿Dónde está el error?
#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

Corregido el tuyo:

#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

Usted debe tener un Lenght de 4 o menos en todas partes

Copiar más de 2GB funciona

Obteniendo la dirección inicial de un array:

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

Su ejemplo en el código es bastante diferente. Estoy tratando de obtener el valor de la dirección.

Hay un ejemplo en el artículo.

He resaltado los lugares donde se escribe por dirección. Sin embargo, este ejemplo del artículo también causa un fallo.

Claro que lo hace... los prototipos son de 4 (dirección de 32 bits a la unsigned int), y los compilas/ejecutas en 5 (tiene 64).

No te puedes fiar de nadie, si usas WinAPI, escribe tu mismo los prototipos. O mejor escribe tu propia DLL, que tire de winapi, y arriba en mql da interfaces de mayor nivel

 
Aliaksandr Hryshyn #:

Copiar más de 2 GB funciona

Obtención de la dirección inicial del array:

Me perdí el punto con la dirección de 64bit. Pero sigo fallando con la dirección corregida. ¿Es seguro que debería funcionar? ¿Puedo ver un ejemplo completo del código fxsaber corregido?

Hasta ahora todavía estoy de mi propia opinión - la dirección de WinAPI es incompatible con MQL.

 
Aliaksandr Hryshyn #:

Arreglado el tuyo:

Maxim Kuznetsov #:

claro que si...los prototipos son de 4 (32 bit address a la unsigned int) y compilan/ejecutan en 5 (tiene 64).

Gracias, ahora funciona.
#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)); // Crash.

  Print(Value);
}
 
fxsaber #:
Gracias, ahora funciona.

El último parámetro (que es cnt) también es de 64 bits. Es 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