2010-12-20 4 views
1

기존 VB6 프로젝트에서 사용할 서비스에 대한 래퍼를 작성하려고합니다. 한 가지 중요한 측면을 제외하고는 대부분의 기본 프레임 워크가 작동합니다. VB6 프로젝트에서 랩퍼를 참조 할 수 있으며 서브/함수 호출 등은 예상대로 작동하지만 이벤트는 그렇지 않습니다. 이벤트는 VB6 앱에서 볼 수 있지만 실행되지는 않습니다.COM에 노출 된 클래스 라이브러리의 이벤트 발생

VB.NET 코드 :

Public Event Action_Response(ByVal Status as String) 
Public Function TestEvent() 
    RaiseEvent Action_Response("Test Done") 
    Return "Done" 
End Function 

VB6 코드 : 예상대로

Dim WithEvents my_Wrapper as Wrapper_Class 
Private Sub cmdTest_Click() 
    Set my_Wrapper = New Wrapper_Class 
    Debug.Print my_Wrapper.TestEvent() 
End Sub 

Private Sub my_Wrapper_Action_Response(ByVal Status As String) 
    Debug.Print Status 
    Set my_Wrapper = Nothing 
End Sub 

그래서, '완료'를 cmdTest 버튼 코드가 ​​인쇄하지만 Action_Response 이벤트가 발생하지 않습니다. 이벤트를 시작하기 위해해야 ​​할 일이 있습니까?

+0

VB.NET 클래스 작성법 문서

+0

@Hans : 클래스 라이브러리 프로젝트를 만들고 기본 클래스를 삭제 한 다음 새 항목을 추가하고 옵션에서 'COM 클래스'를 선택했습니다. – Antagony

+0

이벤트가 제대로 작동하게하려면 를 직접 사용해야했습니다. 나 + + + 자동으로 할 것이지만, 그런 식으로 작동하지 않습니다. – DarinH

답변

7

그것의 너무 많은 코멘트에 작성하는, 그래서 그것을 대답 할 것입니다 ....

먼저, COM에 노출 할 .NET 클래스를 식별합니다. CORE라고 불리는 수업을 골라 듭니다.

CORE 개체가 소스 (즉, 생성)하는 EVENTS를 설명하는 인터페이스를 만듭니다.

<ComVisible(True)> _ 
<Guid("some guid here...use guidgen, I'll call it GUID1")> _ 
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _ 
Public Interface ICoreEvents 
    <System.Runtime.InteropServices.DispId(1)> _ 
    Sub FileLoaded(ByVal Message As String) 
End Interface 

다음으로 클래스의 COM 공개 속성 및 메서드에 대한 인터페이스를 만듭니다. 당신이 당신의 클래스 내에서 FileLoaded 이벤트, 단지 RAISEEVENT FILELOADED (메시지)을 마련 할 필요가있을 때

<ComVisible(True)> _ 
<Guid("another GUID, I'll call it guid2")> _ 
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _ 
Public Interface ICore 
    ReadOnly Property Property1() As Boolean 
    ReadOnly Property AnotherProperty() As ISettings 
    ReadOnly Property Name() As String 
    ReadOnly Property Phone() As String 
End Interface 

자, 이제 실제 .NET 클래스

<ComVisible(True)> _ 
<ClassInterface(ClassInterfaceType.None)> _ 
<ComDefaultInterface(GetType(ICore))> _ 
<ComSourceInterfaces(GetType(ICoreEvents))> _ 
<Guid("a third GUID, I'll call it GUID3")> _ 
Public Class Core 
    Implements ICore 

    <System.Runtime.InteropServices.ComVisible(False)> _ 
    Public Delegate Sub OnFileLoaded(ByVal Message As String) 
    Public Event FileLoaded As OnFileLoaded 
End Class 

을 만들 수 있습니다. COMSourceInterfaces 특성을 연결 했으므로 .NET에서 이벤트를 COM으로 전달합니다.

이 속성은 대부분 이것의 약자이지만, 유감스럽게도 특정 작업 (예 : com 인터페이스의 버전 호환성 유지)에 필요한 제어 권한을 제공하지 않습니다.

+0

자세한 답변을 주셔서 감사합니다. 테스트 할 새 프로젝트를 만들었습니다. 불행히도, 문제가있는 것 같습니다 : "ICore 구현"라인이 속성에 대한 오류를 일으키고 있습니다 - 클래스 'Core'는 'ICore'인터페이스의 'ReadOnly Property Name As String'을 구현해야합니다. 구현 속성은 'ReadOnly'또는 'WriteOnly'지정자와 일치해야합니다. 나 자신을 몇 가지 시도했지만 아무런 확실한 해결책이 나에게 튀어 나오지 않는다. – Antagony

+0

나는 거의 거기에있다, 생각한다.코드를 복사하여 붙여 넣었으므로 VB는 Core 클래스에서 해당 속성을 만들지 못했습니다. Implements 행에서 반환 값을 얻어야 만 문제가 해결되었습니다. D' oh! – Antagony

+0

이제 클래스를 빌드하고 regasm을 사용하여 tlb 파일로 등록했습니다. 클래스는 VB6 테스트 프로젝트에 나타나며 이벤트, 메서드 및 속성에 관한 모든 것이 괜찮아 보입니다. 모두 IDE에 올바르게 표시됩니다.하지만 새 인스턴스를 만들 자마자 클래스의 자동화 오류가 발생합니다. "시스템에서 지정된 파일을 찾을 수 없습니다." 어떤 코드가 어디서나 참조되는 것으로 보이지 않으므로 이상하게 보입니다. – Antagony

관련 문제