Discussion of article "Getting Rid of Self-Made DLLs" - page 3

 
Dmitri Custurov #:
I wonder if it is possible to get a real pointer to a function. Pointers obtained using typedef work perfectly well inside mql program. But unfortunately I failed to pass them into dll.

If you know C++ + built-in assembler and know what and how to put into the stack, and the terms far and near call are clear, you can try. I cannot guarantee that it will work, but it is possible.

 
Where's the mistake?
#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 #:
Where's the mistake?
#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 #:

Your example in the code is quite different. I am trying to get the value from the address.

There is an example in the 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

//+------------------------------------------------------------------+
//| Script programme start function|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- open the memory object
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- get memory pointer
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- read the first 10 bytes from memory
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- write a 4 byte int number to the beginning of memory
  memcpy(view, num, 4);
  //--- close the view
  UnmapViewOfFile(view); 
  //--- close the object
  CloseHandle(hmem); 
}
I have highlighted the places where it is written by address. However, this example from the article also crashes.
 
fxsaber #:

Your example in the code is quite different. I am trying to get the value from the address.

There is an example in the article.

I have highlighted the places where it is written by address. However, this example from the article also causes a crash.

I immediately understood what you wanted. I am sure that the address returned from WinAPI functions cannot be used in MQL5. But the address is passed to the arguments correctly.

You can be absolutely sure by writing a simple DLL that shows the address received in the argument and returns it. And compare the result in MQL5. Many people here practice C.

 
fxsaber #:
Where's the mistake?
#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

Corrected yours:

#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

You should have a Lenght of 4 or less everywhere

Copying more than 2GB works

Getting the starting address of the array:

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

Your example in the code is quite different. I am trying to get the value from the address.

There is an example in the article.

I have highlighted the places where it is written by address. However, this example from the article also causes a crash.

Of course it does... the prototypes are from 4 (32-bit address a la unsigned int), and you compile/run them in 5 (it has 64).

You can't trust anyone, if you use WinAPI - write prototypes yourself. Or better to write your own DLL, let it pull winapi, and upstairs in mql gives interfaces of higher level

 
Aliaksandr Hryshyn #:

Copying more than 2GB works

Getting the initial address of the array:

I missed the point with the 64bit address. But I still crash with the corrected address. Is it sure it should work? Can I see a full example of the corrected fxsaber code?

So far I am still of my own opinion - the address from WinAPI is incompatible with MQL.

 
Aliaksandr Hryshyn #:

Fixed yours:

Maxim Kuznetsov #:

of course it does...prototypes are from 4 (32 bit address a la unsigned int) and compile/run in 5 (it has 64).

Thanks, it works now.
#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 #:
Thanks, it works now.

The last parameter (which is cnt) is also 64 bits. It is 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