2014-10-15 1 views
0

VB6에서 사용되는 간단한 COM 개체를 사용하여 C++ ATL 프로젝트를 개발했습니다. 프록시/스텁 병합을 허용하는 옵션을 선택했습니다. 이 프로젝트는 단일 스레드 아파트 모델, 이중 인터페이스를 사용하고 연결 지점을 지원합니다.COM 디스패치 이벤트를 처리하면 VB6 컴파일 된 코드가 충돌 함

인터페이스 및 디스패치 인터페이스에 메소드를 추가하고 연결 지점 구현 마법사 (연결 포인트 추가)를 실행하여 '실행'메소드를 구현했습니다. COM 개체를 사용하기 위해 VB6에서 테스트 응용 프로그램을 만들었습니다. 한 응용 프로그램은 명명 된 파이프 서버이고 다른 응용 프로그램은 명명 된 파이프 클라이언트입니다.

이러한 응용 프로그램에서 개체에 대한 참조를 추가하고 양식에서 전체적으로 흐리게 표시했습니다. 서버에서 추가로 'WithEvents'를 선언했습니다.
VB6에서 'WithEvents'개체를보고 내 이벤트 처리기 코드를 추가 할 수 있습니다.

VB6에서 재생 (VB6.exe 통해)을 눌러 응용 프로그램을 실행하면 서버가 시작되고 클라이언트가 연결됩니다. 내 서버 이벤트를 발생시키고 vb6 이벤트 처리기 코드를 처리합니다. 이것은 위대하고 단지 내가 원했던 것입니다.

응용 프로그램의 VB6 실행 파일을 빌드하고 실행하면 동일한 이벤트 시퀀스로 인해 서버가 충돌합니다. 충돌하는 코드를 디버깅 할 때 'Fire'코드의 IDispatch :: Invoke 메서드가 있습니다. 한 번 시작된 내 서버는 별도의 스레드에서 실행되어 파이프 연결을 허용합니다. 화재 이벤트가 발생하는 것은이 별도의 스레드에 있습니다.

STA 모델을 위반하는 것일 수 있습니다 (모르겠다). 장기간 실행되는 작업에 이벤트를 사용하는 것에 대해서는 프로그래밍 가이드의 지침을 따랐습니다. 코드 예제에서는 항상 스레드가 생성되고 해당 스레드에서 fire 메서드가 호출되는 것을 보여줍니다. 어떤 통찰력이라도 대단히 감사하겠습니다.

+0

유용한 답변을 얻으려면 _lot_ 세부 정보를 게시해야합니다. – xxbbcc

+4

예, STA를 위반하는 것입니다. 이 * VB6 응용 프로그램을 크래시 것입니다. VB6 런타임에서 만든 STA 스레드에서 이벤트가 발생하도록 스레드에서 인터페이스 포인터를 마샬링해야합니다. 일반적으로 IGlobalInterfaceTable을 사용하는 것이 더 쉬운 방법입니다. –

+0

감사합니다. 이를 연구하고 정확하게 사용 사례를 설명합니다. 이전에 다른 게시물에서 '스레딩 모델을'Free '로 변경하여이 문제를 해결했지만이 점이 더 마음에 듭니다. 나는 '무료'스레딩 모델을 사용하는 데 익숙하지 않습니다. –

답변

0

IGlobalInterfaceTable 인터페이스를 사용하여 다른 아파트에 대한 인터페이스 포인터를 마샬링하는 것에 대한 언급은 정확하게 나의 사용 사례를 설명합니다. 나는이 방법을 시도하고 답을 검증 할 것이다.

+0

실제로 문제가 묻어 있습니다 - VB6는 VB6 개체가 생성 된 STA 이외의 이벤트를받을 수 없습니다. – wqw

+0

감사합니다. 나는 코드로 되돌아 갔고 자유롭게 스레드 된 스레드를 아파트 스레드로 변경했다. 예 : CComSingleThreadModel에서 파생되고 레지스트리 모델을 Apartment로 변경합니다. 제안 된 솔루션을 구현하려고합니다. –

+0

불행히도 나는 대안 솔루션을 얻을 수 없었다. 성공적으로 인터페이스를 등록하고 취소 할 수 있었지만 쿠키를 사용하면 결코 인터페이스를 다시 제공하지 못했습니다. 이것은 매우 실망 스러웠습니다. 또한 내 방법이 효과가 있다고 생각합니다. 나는 하나의 세부 사항을 언급하지 않았다. 디스패치 이벤트는 COM 개체와 동일한 스레드에서 만들어진 포인터 개체에서 시작됩니다. 난 그냥 다른 스레드에서 일을하고 뮤텍스와 함께 세계적으로 차단 일이. –

관련 문제