기고글 토론 "DLL 생성이 불필요한 이유" - 페이지 3

 
Dmitri Custurov #:
함수에 대한 실제 포인터를 얻을 수 있는지 궁금합니다. typedef를 사용하여 얻은 포인터는 mql 프로그램 내에서 완벽하게 작동합니다. 그러나 불행히도 나는 그들을 dll에 전달하지 못했습니다.

C++ + 내장 어셈블러를 알고 있고 스택에 무엇을 어떻게 넣어야하는지 알고 있고 멀리 및 가까운 호출이라는 용어가 명확하다면 시도해 볼 수 있습니다. 나는 그것이 작동 할 것이라고 보장 할 수는 없지만 가능합니다.

 
어디가 실수인가요?
#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)); // 충돌.

  Print(Value);
}
 
fxsaber #:
어디가 실수인가요?
#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 #:

코드의 예제는 상당히 다릅니다. 주소에서 값을 가져오려고 합니다.

문서에 예제가 있습니다.

#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

//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 기능|
//+------------------------------------------------------------------+
void OnStart()
{
  //--- 메모리 객체를 엽니다.
  int hmem=OpenFileMappingW(FILE_MAP_ALL_ACCESS, 0, "Local\\file");
  //--- 메모리 포인터 가져오기
  int view=MapViewOfFile(hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0); 
  //--- 메모리에서 처음 10바이트를 읽습니다.
  uchar src[10];
  memcpy(src, view, 10);
  int num=10;
  //--- 메모리 시작 부분에 4바이트 인티 숫자를 씁니다.
  memcpy(view, num, 4);
  //--- 뷰 닫기
  UnmapViewOfFile(view); 
  //--- 개체 닫기
  CloseHandle(hmem); 
}
주소로 작성된 부분을 강조 표시했습니다. 그러나 이 문서의 예제에서도 충돌이 발생합니다.
 
fxsaber #:

코드의 예제는 상당히 다릅니다. 주소에서 값을 가져오려고 합니다.

문서에 예제가 있습니다.

주소로 작성된 부분을 강조 표시했습니다. 그러나 기사의이 예제는 또한 충돌을 일으 킵니다.

나는 당신이 원하는 것을 즉시 이해했습니다. WinAPI 함수에서 반환 된 주소는 MQL5에서 사용할 수 없다고 확신합니다. 그러나 주소는 인수에 올바르게 전달됩니다.

인수로받은 주소를 표시하고 반환하는 간단한 DLL을 작성하면 절대적으로 확신 할 수 있습니다. 그리고 그 결과를 MQL5에서 비교해 보세요. 많은 사람들이 C를 사용합니다.

 
fxsaber #:
어디가 실수인가요?
#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

정정했습니다:

#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

모든 곳에서 길이가 4 이하여야 합니다.

2GB 이상 복사 가능

배열의 시작 주소 가져오기:

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

코드의 예제는 상당히 다릅니다. 주소에서 값을 가져오려고 합니다.

문서에 예제가 있습니다.

주소로 작성된 부분을 강조 표시했습니다. 그러나 기사의 이 예제에서도 충돌이 발생합니다.

물론 그렇습니다... 프로토타입은 4(32비트 주소, 부호 없는 int)에서 컴파일/실행하고, 5(64)에서 컴파일/실행합니다.

WinAPI를 사용하는 경우 아무도 신뢰할 수 없으므로 프로토 타입을 직접 작성하십시오. 또는 직접 DLL을 작성하여 WinAPI를 가져오고 mql의 위층에서 더 높은 수준의 인터페이스를 제공하는 것이 더 좋습니다.

 
Aliaksandr Hryshyn #:

2GB 이상 복사 작업

배열의 초기 주소 가져오기:

64비트 주소로 요점을 놓쳤습니다. 하지만 수정된 주소에서도 여전히 충돌이 발생합니다. 제대로 작동하는 게 맞나요? 수정된 fxsaber 코드의 전체 예제를 볼 수 있나요?

지금까지는 여전히 제 개인적인 의견입니다. WinAPI의 주소가 MQL과 호환되지 않습니다.

 
Aliaksandr Hryshyn #:

수정했습니다:

막심 쿠즈네초프 #:

물론 그렇습니다... 프로토 타입은 4 (32 비트 주소는 서명되지 않은 int)에서 5로 컴파일 / 실행됩니다 (64 개 있음).

고마워요, 이제 작동합니다.
#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)); // 충돌.

  Print(Value);
}
 
fxsaber #:
감사합니다, 이제 작동합니다.

마지막 매개 변수(cnt)도 64비트입니다. 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