Discussão do artigo "Eliminação de DLLs autogeradas" - página 3

 
Dmitri Custurov #:
Gostaria de saber se é possível obter um ponteiro real para uma função. Os ponteiros obtidos usando typedef funcionam perfeitamente bem no programa mql. Mas, infelizmente, não consegui passá-los para a dll.

Se você conhece C++ + assembler embutido e sabe o que e como colocar na pilha, e os termos chamada distante e próxima estão claros, você pode tentar. Não posso garantir que funcionará, mas é possível.

 
Onde está o erro?
#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 #:
Onde está o erro?
#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 #:

Seu exemplo no código é bem diferente. Estou tentando obter o valor do endereço.

Há um exemplo no artigo.

#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

//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- abrir o objeto de memória
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- obter ponteiro de memória
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- ler os primeiros 10 bytes da memória
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- escrever um número int de 4 bytes no início da memória
  memcpy(view, num, 4);
  //--- fechar a visualização
  UnmapViewOfFile(view); 
  //--- fechar o objeto
  CloseHandle(hmem); 
}
Eu destaquei os locais onde está escrito por endereço. No entanto, esse exemplo do artigo também falha.
 
fxsaber #:

Seu exemplo no código é bem diferente. Estou tentando obter o valor do endereço.

Há um exemplo no artigo.

Eu destaquei os locais onde está escrito por endereço. Entretanto, esse exemplo do artigo também causa uma falha.

Entendi imediatamente o que você queria. Tenho certeza de que o endereço retornado das funções WinAPI não pode ser usado em MQL5. Mas o endereço é passado para os argumentos corretamente.

Você pode ter certeza absoluta escrevendo uma DLL simples que mostre o endereço recebido no argumento e o retorne. E compare o resultado em MQL5. Muitas pessoas aqui praticam C.

 
fxsaber #:
Onde está o erro?
#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

Corrigido o seu:

#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

Você deve ter um comprimento de 4 ou menos em todos os lugares

A cópia de mais de 2 GB funciona

Obtendo o endereço inicial de uma matriz:

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

Seu exemplo no código é bem diferente. Estou tentando obter o valor do endereço.

Há um exemplo no artigo.

Eu destaquei os locais onde está escrito por endereço. Entretanto, esse exemplo do artigo também causa uma falha.

É claro que sim... os protótipos são de 4 (endereço de 32 bits a la unsigned int), e você os compila/executa em 5 (tem 64).

Se você usa WinAPI, não pode confiar em ninguém - escreva protótipos você mesmo. Ou melhor, escreva sua própria DLL, deixe-a puxar o winapi e, lá em cima, no mql, forneça interfaces de nível superior

 
Aliaksandr Hryshyn #:

A cópia de mais de 2 GB funciona

Obtendo o endereço inicial da matriz:

Errei o ponto com o endereço de 64 bits. Mas continuo travando com o endereço corrigido. Tem certeza de que deve funcionar? Posso ver um exemplo completo do código fxsaber corrigido?

Até agora, continuo com minha própria opinião - o endereço da WinAPI é incompatível com o MQL.

 
Aliaksandr Hryshyn #:

Corrigido o seu:

Maxim Kuznetsov #:

é claro que sim... os protótipos são do 4 (endereço de 32 bits a la int sem sinal) e compilam/executam no 5 (ele tem 64).

Obrigado, agora está funcionando.
#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 #:
Obrigado, agora está funcionando.

O último parâmetro (que é cnt) também é de 64 bits. Ele é 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