2012-01-23 6 views
2

내 문제는 간단하다, 나는이 부울 인수 밖으로 전달하는 VB6 라이브러리에 선언 된 이벤트 : 내 C# 코드를 위로 구부려 한VB6 이벤트 전달 부울 인수

Public Event WriteComplete(ByVal aCommsOk As Boolean, ByVal aBadPIN As Boolean) 

을 이 이벤트에 여러 번이나 기이하게도 테스트 부서와 다른 두 사람이 VB6에서 aBadPIN을 false로 설정하여이 이벤트를 발생 시키지만 C# 이벤트 핸들러는이를 사실로 수신한다는 사실을 알게되었습니다. 일관성이 없기 때문에 '그'문제 중 하나이지만 인터넷에서 도움이되는 내용을 찾지는 못합니다.

부울을 바이트로 변환하고 전송 한 새로운 이벤트를 정의한 다음 C#으로 다시 변환하면 문제가있는 시스템에서 문제가 해결된다는 사실을 발견했습니다. 그러나 필자는 COM과 .NET 라이브러리간에 마샬링되는 모든 단일 부울에 대해이를 수행해야하므로 실제로 그렇게하고 싶지는 않습니다.

EAX 레지스터를 false로 올바르게 표현하려면 EAX 레지스터를 강제해야하는 버그 (적어도 C++에서는)가 있지만 어쨌든 전에는이 문제가 없었던 곳을 솔직하게 읽었습니다. 어쨌든 VB6에서 그 일을 시작하십시오.

모든 아이디어가 우수 할 것입니다.

업데이트 : 로깅은이 문제가 발생하면 이벤트를 발생시키는 호출이 C# 이벤트 처리기가 실행되기 전에 VB6 코드로 제어를 반환한다는 것을 보여줍니다. 그게 뭐야?

업데이트 : 발생 코드가 종료 된 후에도 여전히 이벤트 처리기에서 이벤트를 수신하고 있지만 변경 사항을 마샬링하지 않으려 고 시도했습니다. 시간 제약으로 슬프게도 래퍼를 추가해야합니다.

+0

C# interop 게시는 유용 할 것입니다. – vcsjones

+4

VB 6에서'false'는 0으로 표현되고'true'는 -1로 표현됩니다 (또는 NOT false). 부울 값을 C# 측에서 올바르게 마샬링하지 않거나 잘못된 숫자 리터럴을 검사하는 경우 잘못된 결과를 얻게됩니다. 물론, vcsjones가 말했듯이, 나머지 코드를 제공하지 않으면 디버깅이 불가능합니다. –

+1

VB는 VARIANT_BOOL 유형을 사용하며, 이는 짧음 (16 비트)입니다. 이것을 32 비트로 정렬하면 다른 16 비트가 0이 아닌 경우 False가 True로 표시됩니다. 명시 적 마샬링을하고 계시거나 COM interop에서 모든 것을 처리하고 있습니까? – arx

답변

3

죄송합니다. 문제는 VB6 환경에서 비트 단위 부울만큼 간단하지 않았습니다.

문제가 마샬링되면 .NET이 만드는 interop DLL이 어떻게 든 해당 VB6 DLL과 동기화되지 않을 가능성이 있습니까? (제쳐두고 VB6의 이진 호환성 설정에 대해 잘 알고 있습니까?)

위의 질문에 대해 다음과 같이했습니다.이 단순한 프로젝트 집합이 코딩 또는 마샬링 문제의 대표 모델인지 알려 주시기 바랍니다. 당신은 추적하고 있습니다. 이 문제가 마샬링되면 C# 및 vb6 프로젝트의 단순화 된 버전을 추적하여이를 추적하는 것이 도움이 될 수 있습니다.

Public Event WriteComplete(ByVal aCommsOk As Boolean, ByVal aBadPIN As Boolean) 

Public Sub DoIt(ByVal Mode As Integer) 
    RaiseEvent WriteComplete(CBool(Mode And 1), CBool(Mode And 2)) 
End Sub 
VS2003와

(옛 .NET,하지만 여전히 적용한다)는, 나는 간단한 C#을 만들어 : VB6와

, 나는 BoolBuster라는 클래스와 간단한 ActiveX DLL을 (LibBoolBuster라는 이름의 프로젝트를) 생성 Windows 응용 프로그램, 4 개의 단추가있는 양식 및 위의 VB6 ActiveX DLL에 대한 참조 만들기. VB6 DLL에 액세스하는 양식의 멤버를 만들었습니다.

public LibBoolBuster.BoolBuster vb6Obj = new LibBoolBuster.BoolBuster(); 

via Interop is LibBoolBuster; BoolBuster 클래스에는 event와 DoIt 멤버가 있습니다.양식 초기화에서, 이벤트 인맥은과 같이 수행됩니다

private void vb6Obj_WriteComplete (System.Boolean aCommsOk , System.Boolean aBadPIN) 
{ 
    MessageBox.Show(aCommsOk.ToString() + ", " + aBadPIN.ToString());   
} 

각 버튼 클릭 이벤트 핸들러가 DOIT에 간단한 호출을 :

vb6Obj.WriteComplete += new LibBoolBuster.__BoolBuster_WriteCompleteEventHandler(vb6Obj_WriteComplete); 

WriteComplete 이벤트 핸들러 양식의 회원입니다 :

vb6Obj.DoIt(0); 

(및 vb6Obj.DoIt (1) vb6Obj.DoIt (2) 등)

매우 단순한 프로 ject : 버튼을 클릭하면 DoIt이 호출되고 WriteComplete 이벤트가 발생합니다. 나는 그것을 시험해 보았고, 예상대로 일을했다.


VB6 측면을 자세히 살펴보십시오. 이벤트가 발생한 것으로 나타났습니다 :

RaiseEvent WriteComplete(aCommsReceived, Not (aIsAcknowledged)) 

감사원이 0 또는 -1인지 확인하십시오. 그렇지 않으면 예상 한 결과를 얻지 못할 것입니다.

VB6 부울 연산자는 모두 비트 단위입니다. 즉 (1이 아님) -2가 0이 아닙니다.

또한 VB6에서는 Integer에서 Boolean으로 변환 할 때 0이 아닌 정수가 True로 매핑됩니다. 0 만 false가됩니다.

+2

이걸 추가하기 만하면 'Not (CBool ​​(aIsAcknowledged))'를 사용하게됩니다. –

+0

Well aIsAcknowledged는 이미 bool이며 런타임에이 문제가 발생하면 true로 기록됩니다. 어쩌면 마샬링 할 때 변환하지 않는 것이 현명하지 않을까요? 나는 그것을 시도하지 않았지만 내일 당신에게 알려줄 것입니다. – Akuma

+0

슬프게도 bool을 로컬로 생성하고 반환하기 전에 false로 설정하는 것은 동일한 효과가 있으므로 마샬링 문제입니다. – Akuma