"Getting Rid of Self-Made DLLs" makalesi için tartışma - sayfa 3

 
Dmitri Custurov #:
Bir fonksiyona gerçek bir işaretçi almanın mümkün olup olmadığını merak ediyorum. Typedef kullanılarak elde edilen işaretçiler mql programı içinde mükemmel çalışıyor. Ama ne yazık ki dll içine aktarmayı başaramadım.

C++ + built-in assembler biliyorsanız ve stack'e neyi nasıl koyacağınızı biliyorsanız ve far ve near call terimleri açıksa deneyebilirsiniz. Çalışacağını garanti edemem ama mümkün.

 
Hata nerede?
#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 #:
Hata nerede?
#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 #:

Koddaki örneğiniz oldukça farklı. Adresten değer almaya çalışıyorum.

Makalede bir örnek var.

#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

//+------------------------------------------------------------------+
//| Betik program başlatma işlevi|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- bellek nesnesini açın
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- bellek işaretçisini al
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- bellekten ilk 10 baytı okuyun
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- belleğin başına 4 baytlık bir int sayı yazın
  memcpy(view, num, 4);
  //--- görünümü kapatın
  UnmapViewOfFile(view); 
  //--- nesneyi kapatın
  CloseHandle(hmem); 
}
Adrese göre yazıldığı yerleri vurguladım. Ancak, makaledeki bu örnek de çöküyor.
 
fxsaber #:

Koddaki örneğiniz oldukça farklı. Adresten değer almaya çalışıyorum.

Makalede bir örnek var.

Adres ile yazıldığı yerleri vurguladım. Ancak makaledeki bu örnek de çökmeye neden oluyor.

Ne istediğinizi hemen anladım. WinAPI fonksiyonlarından dönen adresin MQL5'te kullanılamayacağına eminim. Ancak adres argümanlara doğru bir şekilde aktarılır.

Argümanda alınan adresi gösteren ve döndüren basit bir DLL yazarak kesinlikle emin olabilirsiniz. Ve sonucu MQL5'te karşılaştırın. Burada birçok kişi C kullanıyor.

 
fxsaber #:
Hata nerede?
#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

Seninki düzeltildi:

#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

Her yerde 4 veya daha az uzunluğa sahip olmalısınız

2 GB'den fazla kopyalama çalışıyor

Dizinin başlangıç adresini alır:

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

Koddaki örneğiniz oldukça farklı. Adresten değer almaya çalışıyorum.

Makalede bir örnek var.

Adres ile yazıldığı yerleri vurguladım. Ancak makaledeki bu örnek de çökmeye neden oluyor.

Tabii ki yapar... prototipler 4'ten (32 bit adres a la unsigned int) ve bunları 5'te derler / çalıştırırsınız (64'e sahiptir).

WinAPI kullanırsanız kimseye güvenemezsiniz - prototipleri kendiniz yazın. Ya da kendi DLL'inizi yazmak, winapi'yi çekmesine izin vermek ve mql'de üst katta daha yüksek seviyeli arayüzler vermek daha iyidir

 
Aliaksandr Hryshyn #:

2 GB'den fazla kopyalama çalışıyor

Dizinin başlangıç adresini alır:

64bit adresle ilgili noktayı kaçırmışım. Ama düzeltilmiş adresle hala çöküyorum. Çalışması gerektiğinden emin misiniz? Düzeltilmiş fxsaber kodunun tam bir örneğini görebilir miyim?

Şimdiye kadar hala kendi görüşümdeyim - WinAPI'den gelen adres MQL ile uyumsuz.

 
Aliaksandr Hryshyn #:

Seninkini düzelttim:

Maxim Kuznetsov #:

Elbette öyle... prototipler 4'ten (32 bit adres a la unsigned int) ve 5'te (64'e sahiptir) derlenir / çalıştırılır.

Teşekkürler, şimdi çalışıyor.
#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 #:
Teşekkürler, şimdi çalışıyor.

Son parametre (cnt olan) de 64 bittir. Bu 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