서로 다른 터미널에서 작동하는 두 개의 Expert Advisor 간의 데이터 교환 - 페이지 4

 

레지스트리를 괴롭히는 것의 대안으로 - 간단한 파일 교환. (파일 시스템이 NTFS라고 가정)

각 코스 \experts\files에는 2개의 터미널 c:\mt1, c:\mt2가 있습니다.

Exchange 폴더 생성 c:\mt1\experts\files\ exchange c:\mt2\experts\files\ exchange

Vista MKLINK의 Windows Server 2003 Resource Kit 도구 (win 2000,2003,xp용)에서 linkd 명령으로 링크 만들기

linkd.exe c:\ mt1 \experts\files\ exchange c:\ mt2 \experts\files\ exchange

이제 터미널의 공통 디렉토리입니다. (모든 파일을 c:\ mt1 \experts\files\ exchange에 복사하고 c:\ mt2 \experts\files\ exchange 디렉토리를 찾습니다. )

Far - Alt F6으로도 동일한 작업을 수행할 수 있습니다.

 
JavaDev >> :

레지스트리를 괴롭히는 것의 대안으로 - 간단한 파일 교환. (파일 시스템이 NTFS라고 가정)

각 코스 \experts\files에는 2개의 터미널 c:\mt1, c:\mt2가 있습니다.

Exchange 폴더 생성 c:\mt1\experts\files\ exchange c:\mt2\experts\files\ exchange

Vista MKLINK의 Windows Server 2003 Resource Kit 도구 (win 2000,2003,xp용)에서 linkd 명령으로 링크 만들기

linkd.exe c:\ mt1 \experts\files\ exchange c:\ mt2 \experts\files\ exchange

이제 터미널의 공통 디렉토리입니다. (모든 파일을 c:\ mt1 \experts\files\ exchange에 복사하고 c:\ mt2 \experts\files\ exchange 디렉토리를 찾습니다. )

Far - Alt F6으로도 동일한 작업을 수행할 수 있습니다.

그러나 파일을 통한 통신은 올바른 도구가 아닙니다. 일부러가 아닙니다.

파일은 정보의 장기 저장을 위해 설계되었습니다. 왜 디스크로 귀찮게합니까? 통신용 RAM이 있습니다.

 
Andres >> :

그 후에 밝혀졌습니다.

2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1: ####
2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1: RegCreateKeyExA(): 존재하지 않는 파티션이 생성되었습니다.
2009.05.19 01:22:16 온도 테스트 시작

즉, 호출 중에 오류가 발생하지 않더라도 버퍼의 내용은 변경되지 않습니다. 그리고 레지스트리에는 "Test"라는 문자열이 정확히 포함되어 있습니다.

포럼 게시물에서 이것은 MQL 환경에서 DLL 함수로 문자열이 비정상적으로 전달되기 때문임을 이해했습니다. MQL 환경에서 개발자는 자체 관리자(문자열 풀)를 사용하여 문자열에 대해 작업하고 분명히 이 경계에서 잘못된 버퍼가 채워지고 있으므로 API 함수에서 반환된 결과를 볼 수 없습니다. 그러나 전체 최대 길이로 초기화된 문자열을 사용하면 내가 아는 한 문제가 없습니다. 이것이 255자 "#"으로 된 줄이 있는 이유입니다. "#" 기호는 단순히 선이 눈에 보이도록 하기 위해 선택되었습니다. 호출 전에 버퍼가 어떻게 채워지는지는 중요하지 않기 때문에 이것은 Win API 자체와 관련이 없습니다. 이것은 앞서 언급한 선의 길이에 대한 제한입니다. 255자보다 큰 문자열을 SetStringValue()에 전달할 수 있지만 읽을 수는 없습니다.

물론 제약이 없을 때 좋은데 큰 불편함은 못느끼겠습니다. 질문이 생깁니다. 왜 주어진 크기의 문자열을 읽어야 합니까? 제한 사항인 경우 레지스트리에 기록할 때 소스 문자열을 길이 255 + "잔여" 매개변수의 N 매개변수로 분할하는 함수를 작성하여 이를 우회할 수도 있습니다. 그리고 읽을 때 - 다시 수집합니다. 그것은 다른 방법과 같습니다. 어렵다고 생각되면 저에게 연락하십시오. 제가 하겠습니다. 모든 사람의 요구 사항이 다르고 모든 것을 예측할 수는 없으며 이것만으로도 충분하고 누군가는 여러 수준에서 전역 변수를 사용합니다.

이해가 안되요... 255자 제한이 어디있나요? MQL4에는 그러한 제한이 없다는 것을 확실히 알고 있습니다.

코드 예제는 문제의 본질에 대한 미묘한 힌트였습니다 :-))

 
Zhunko >> :

그러나 파일을 통한 통신은 올바른 도구가 아닙니다. 일부러가 아닙니다.

파일은 정보의 장기 저장을 위해 설계되었습니다. 왜 디스크로 귀찮게합니까? 통신용 RAM이 있습니다.

부분적으로 동의합니다.

RAM을 통해 가능하지만 어렵습니다(모두 동일하게 포럼은 100% 시스템 프로그래머가 아니며 50%도 아닙니다).

그리고 조금 더 넓게 보면 - 유닉스에서는 - 모든 파일과 RAM, 디스크와 프로세스가 있습니다.

여러 가지 방법 중 하나를 제안했습니다.

 
Zhunko >> :

이해가 안되요... 255자 제한이 어디있나요? MQL4에는 그러한 제한이 없다는 것을 확실히 알고 있습니다.

코드 예제는 문제의 본질에 대한 미묘한 힌트였습니다 :-))

글쎄, 프로그램 실행 중에 문자열을 늘리면 제한이 없지만 더 이상 문자열 상수가 아닌 것으로 판명되었습니다. 그리고 여기 에 문자열 상수의 길이에 대해 문서는 다음과 같이 명확하게 말합니다.

문자열 상수의 길이는 0 - 255자입니다. 문자열 상수의 길이가 최대 길이를 초과하면 오른쪽에 있는 추가 문자가 삭제되고 컴파일러에서 적절한 경고를 발행합니다.

 
Andres >> :

글쎄, 프로그램 실행 중에 문자열을 늘리면 제한이 없지만 더 이상 문자열 상수가 아닌 것으로 판명되었습니다. 그리고 여기 에 문자열 상수의 길이에 대해 문서는 다음과 같이 명확하게 말합니다.

우리의 경우 상수인지 아닌지는 중요하지 않습니다.

변수를 통해 더 많은 것이 가능하다는 것을 의미합니까?

 
Zhunko >> :

우리의 경우 상수인지 아닌지는 중요하지 않습니다.

변수를 통해 더 많은 것이 가능하다는 것을 의미합니까?

중요하지 않은 이유는 무엇입니까? 상수 문자열 형식의 버퍼를 사용하면 API 호출이 예상대로 작동하고 "동적으로" 생성된 문자열의 버퍼를 사용하면 API 호출이 오류 없이 작동하기 때문에 중요한(!) 요점입니다. 그러나 앞에서 설명한 이유로 인해 이 문자열에서 레지스트리의 데이터를 관찰하지 않습니다.


안드레스 쓴 >>
글쎄, 프로그램 실행 중에 문자열을 늘리면 제한이 없지만 더 이상 문자열 상수가 아닌 것으로 판명되었습니다. 그리고 여기 문자열 상수의 길이에 대해 문서는 다음과 같이 명확하게 말합니다.

여기서는 라이브러리 제한이 아니라 문자열 길이 제한에 대해 이야기했습니다.

문자열 상수를 사용하고 동적으로 증분된 문자열을 사용하여 레지스트리에서 데이터를 가져오려고 하면 차이점을 알 수 있습니다. 첫 번째 경우에는 데이터가 제공되고 두 번째 경우에는 데이터가 제공되지 않습니다.

 
Andres >> :

여기서는 라이브러리 제한이 아니라 문자열 길이 제한에 대해 이야기했습니다.

문자열 상수를 사용하고 동적으로 증분된 문자열을 사용하여 레지스트리에서 데이터를 가져오려고 하면 차이점을 알 수 있습니다. 첫 번째 경우에는 데이터가 제공되고 두 번째 경우에는 데이터가 제공되지 않습니다.

멋지다! ... 함수의 메모리가 할당되는 위치가 중요하다는 것이 밝혀졌습니다.

 

IMHO 프로그램 간에 데이터를 공유 하는 가장 좋은 방법은 가상 파일을 사용하는 것입니다.

 // Открываем объект-отображение FILE_MAP_READ

hMMF = OpenFileMapping ( FILE_MAP_WRITE , FALSE , lpFileShareName ) ;

// Если открыть не удалось, выводим код ошибки

if ( hMMF = = NULL ) {

MessageBox ( NULL , "OpenFileMapping: Error" , "RealTimeData" , MB_OK ) ;

return 0 ;

}

// Выполняем отображение файла на память FILE_MAP_READ 

// В переменную lpMMF будет записан указатель на отображаемую область памяти

lpMMF = MapViewOfFile ( hMMF , FILE_MAP_WRITE , 0 , 0 , sizeof ( NSDTfeedTick ) ) ;

// Если выполнить отображение не удалось, выводим код ошибки

if ( lpMMF = = 0 ) {

MessageBox ( NULL , "MapViewOfFile: Error" , "RealTimeData" , MB_OK ) ;

return 0 ;

}

//---

등.....

모든 것이 결함 없이 안정적으로 작동합니다. .... 전자 장치로 확인됩니다. :)

 
klot >> :

IMHO 프로그램 간에 데이터를 공유하는 가장 좋은 방법은 가상 파일을 사용하는 것입니다.

등.....

모든 것이 결함 없이 안정적으로 작동합니다. .... 전자 장치로 확인됩니다. :)

맞아요. FileMapping은 가장 쉬운 것은 아니지만 훌륭한 도구입니다. 파이프나 메일슬롯을 사용해 볼 수도 있습니다.