Diskussion zum Artikel "Den Ballast selbstgemachter "dynamischer Programmbibliotheken" loswerden" - Seite 3

 
Dmitri Custurov #:
Ich frage mich, ob es möglich ist, einen echten Zeiger auf eine Funktion zu erhalten. Zeiger erhalten mit typedef funktionieren perfekt gut innerhalb mql-Programm. Aber leider ist es mir nicht gelungen, sie in dll zu übergeben.

Wenn Sie C++ und den eingebauten Assembler beherrschen und wissen, was und wie man in den Stack einfügt, und die Begriffe far und near call klar sind, können Sie es versuchen. Ich kann nicht garantieren, dass es funktionieren wird, aber es ist möglich.

 
Wo liegt der Fehler?
#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)); // Absturz.

  Print(Value);
}
 
fxsaber #:
Wo liegt der Fehler?
#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 #:

Ihr Beispiel im Code ist ganz anders. Ich versuche, den Wert von der Adresse zu erhalten.

Es gibt ein Beispiel in dem Artikel.

#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

//+------------------------------------------------------------------+
//| Skript-Programmstartfunktion|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- das Speicherobjekt öffnen
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- Speicherzeiger erhalten
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- Lesen der ersten 10 Bytes aus dem Speicher
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- eine 4-Byte-Int-Zahl an den Anfang des Speichers schreiben
  memcpy(view, num, 4);
  //--- Schließen der Ansicht
  UnmapViewOfFile(view); 
  //--- das Objekt schließen
  CloseHandle(hmem); 
}
Ich habe die Stellen hervorgehoben, an denen die Adresse geschrieben wird. Allerdings stürzt auch dieses Beispiel aus dem Artikel ab.
 
fxsaber #:

Ihr Beispiel im Code ist ganz anders. Ich versuche, den Wert von der Adresse zu erhalten.

Es gibt ein Beispiel in dem Artikel.

Ich habe die Stellen hervorgehoben, an denen mit Adresse geschrieben wird. Aber auch dieses Beispiel aus dem Artikel verursacht einen Absturz.

Ich habe sofort verstanden, was Sie wollten. Ich bin sicher, dass die von WinAPI-Funktionen zurückgegebene Adresse in MQL5 nicht verwendet werden kann. Aber die Adresse wird korrekt an die Argumente übergeben.

Sie können absolut sicher sein, indem Sie eine einfache DLL schreiben, die die im Argument empfangene Adresse anzeigt und zurückgibt. Und vergleichen Sie das Ergebnis in MQL5. Viele Leute hier praktizieren C.

 
fxsaber #:
Wo liegt der Fehler?
#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

Ich habe deinen korrigiert:

#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

Sie sollten überall eine Länge von 4 oder weniger haben

Kopieren von mehr als 2GB funktioniert

Ermitteln der Startadresse eines Arrays:

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

Ihr Beispiel im Code ist ganz anders. Ich versuche, den Wert von der Adresse zu erhalten.

Es gibt ein Beispiel in dem Artikel.

Ich habe die Stellen hervorgehoben, an denen mit Adresse geschrieben wird. Aber auch dieses Beispiel aus dem Artikel verursacht einen Absturz.

Natürlich tut es das... die Prototypen sind von 4 (32-Bit-Adresse a la unsigned int), und Sie kompilieren/führen sie in 5 (es hat 64).

Sie können niemandem trauen, wenn Sie WinAPI verwenden, schreiben Sie Prototypen selbst. Oder besser, schreiben Sie Ihre eigene DLL, lassen Sie es winapi ziehen, und oben in mql gibt Schnittstellen der höheren Ebene

 
Aliaksandr Hryshyn #:

Kopieren von mehr als 2 GB funktioniert

Ermitteln der Anfangsadresse des Arrays:

Ich habe den Punkt mit der 64bit-Adresse übersehen. Aber ich stürze trotzdem mit der korrigierten Adresse ab. Ist es sicher, dass es funktionieren sollte? Kann ich ein vollständiges Beispiel für den korrigierten fxsaber-Code sehen?

Bis jetzt bin ich immer noch der Meinung, dass die Adresse von WinAPI nicht mit MQL kompatibel ist.

 
Aliaksandr Hryshyn #:

Sie haben Ihre korrigiert:

Maxim Kuznetsov #:

natürlich tut es das...Prototypen sind von 4 (32 Bit Adresse a la unsigned int) und kompilieren/laufen in 5 (es hat 64).

Danke, jetzt funktioniert es.
#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)); // Absturz.

  Print(Value);
}
 
fxsaber #:
Danke, jetzt funktioniert es.

Der letzte Parameter (cnt) ist ebenfalls 64 Bit groß. Es ist 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