Discussion de l'article "Se débarrasser des DLL auto-produites" - page 3

 
Dmitri Custurov #:
Je me demande s'il est possible d'obtenir un vrai pointeur sur une fonction. Les pointeurs obtenus à l'aide de typedef fonctionnent parfaitement dans le programme mql. Mais malheureusement, je n'ai pas réussi à les passer dans la dll.

Si vous connaissez le C++ + l'assembleur intégré et que vous savez quoi et comment mettre dans la pile, et que les termes far et near call sont clairs, vous pouvez essayer. Je ne peux pas garantir que cela fonctionnera, mais c'est possible.

 
Où est l'erreur ?
#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 #:
Où est l'erreur ?
#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 #:

Votre exemple dans le code est tout à fait différent. J'essaie d'obtenir la valeur de l'adresse.

Il y a un exemple dans l'article.

#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

//+------------------------------------------------------------------+
//| Fonction de démarrage du programme de script|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- ouvrir l'objet mémoire
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- obtenir un pointeur de mémoire
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- lire les 10 premiers octets de la mémoire
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- écrire un nombre int de 4 octets au début de la mémoire
  memcpy(view, num, 4);
  //--- fermer la vue
  UnmapViewOfFile(view); 
  //--- fermer l'objet
  CloseHandle(hmem); 
}
J'ai mis en évidence les endroits où l'adresse est écrite. Cependant, cet exemple de l'article se plante également.
 
fxsaber #:

Votre exemple dans le code est tout à fait différent. J'essaie d'obtenir la valeur de l'adresse.

Il y a un exemple dans l'article.

J'ai mis en évidence les endroits où l'adresse est écrite. Cependant, cet exemple de l'article provoque également un plantage.

J'ai immédiatement compris ce que vous vouliez. Je suis certain que l'adresse renvoyée par les fonctions WinAPI ne peut pas être utilisée dans MQL5. Mais l'adresse est correctement transmise aux arguments.

Vous pouvez en être absolument sûr en écrivant une simple DLL qui affiche l'adresse reçue dans l'argument et la renvoie. Comparez ensuite le résultat avec MQL5. Beaucoup de gens ici pratiquent le C.

 
fxsaber #:
Où est l'erreur ?
#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

Corrigée la vôtre :

#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

Vous devez avoir une longueur de 4 ou moins partout.

Copier plus de 2GB fonctionne

Obtenir l'adresse de départ d'un tableau :

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

Votre exemple dans le code est tout à fait différent. J'essaie d'obtenir la valeur de l'adresse.

Il y a un exemple dans l'article.

J'ai mis en évidence les endroits où l'adresse est écrite. Cependant, cet exemple de l'article provoque également un plantage.

Bien sûr... les prototypes sont de 4 (adresse 32 bits comme unsigned int), et vous les compilez/exécutez en 5 (il y en a 64).

Vous ne pouvez faire confiance à personne si vous utilisez WinAPI - écrivez les prototypes vous-même. Ou mieux, écrivez votre propre DLL, laissez-la tirer winapi, et en haut dans mql donne des interfaces de plus haut niveau.

 
Aliaksandr Hryshyn #:

La copie de plus de 2 Go fonctionne

Obtenir l'adresse initiale du tableau :

J'ai raté le coche avec l'adresse 64bit. Mais je me plante toujours avec l'adresse corrigée. Est-ce que c'est sûr que ça devrait marcher ? Puis-je voir un exemple complet du code corrigé de fxsaber ?

Jusqu'à présent, je suis toujours d'avis que l'adresse de WinAPI est incompatible avec MQL.

 
Aliaksandr Hryshyn #:

Corrigez le vôtre :

Maxim Kuznetsov #:

bien sûr que oui...les prototypes sont de 4 (adresse 32 bits à la unsigned int) et compilent/exécutent en 5 (il y en a 64).

Merci, ça marche maintenant.
#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 #:
Merci, cela fonctionne maintenant.

Le dernier paramètre (qui est cnt) est également de 64 bits. Il s'agit de 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