2016-10-24 1 views
0

dll에서 사용자 정의 이벤트 인수 클래스를 내 메인 프로그램에 전달하려고합니다. 둘 다 이벤트 인수 클래스가 정의되어 있지만 이벤트 대리자를 메서드에 바인딩하려고하면 서명이 호환되지 않기 때문에 바인딩하지 않습니다. 코드를 주요 문제로 옮겼습니다. 메인 프로그램은 DLL을로드하고 방법 ShowValue에 이벤트 대리자를 결합vb.net dll 리플렉션 이벤트

Public Class Main 
    Public Event ValueChange(ByVal sender As System.Object, ByVal e As ValueEventArgs) 
    Private _Value As Integer 

    Public Sub Up() 
    _Value += 1 
    RaiseEvent ValueChange(Me, New ValueEventArgs(_Value)) 
    End Sub 
End Class 

Public Class ValueEventArgs 
    Inherits System.EventArgs 
    Public Property Value As Integer 

    Public Sub New(ByVal Value As Integer) 
    Me.Value = Value 
    End Sub 
End Class 

:

Imports System.Reflection 

Public Class Main 
    Private DriverAssembly As [Assembly] 
    Private DriverClass As Type 
    Private DriverClassInstance As Object 

    Private Sub ButtonLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonLoad.Click 
    DriverAssembly = [Assembly].Load("reflection_event, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 
    DriverClass = DriverAssembly.GetType("ReflectionEventDll.Main") 
    DriverClassInstance = Activator.CreateInstance(DriverClass) 

    ' get the handler method 
    Dim Method As MethodInfo = Me.GetType.GetMethod("ShowValue") 

    ' get the event and create a delegate 
    Dim ValueChangeEvent As EventInfo = DriverClass.GetEvent("ValueChange") 
    Dim Handler As [Delegate] = [Delegate].CreateDelegate(ValueChangeEvent.EventHandlerType, Me, Method) ' Fails 
    ' Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type. 

    ' add the event handler 
    ValueChangeEvent.AddEventHandler(DriverClassInstance, Handler) 
    End Sub 

    Private Sub ButtonUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUp.Click 
    DriverClass.GetMethod("Up").Invoke(DriverClassInstance, Nothing) ' invoke the method on the driver class instance 
    End Sub 

    Public Sub ShowValue(ByVal sender As Object, ByVal e As ValueEventArgs) 
    MessageBox.Show(e.Value.ToString()) 
    End Sub 
End Class 

Public Class ValueEventArgs 
    Inherits System.EventArgs 
    Public Property Value As Integer 

    Public Sub New(ByVal Value As Integer) 
    Me.Value = Value 
    End Sub 
End Class 

는 DLL의 코드는 인수로 ValueEventArgs와 ValueChange라는 이벤트를 발생 대리인 및 AddEventHandler의 생성을 제거하면 모든 이벤트가 발생하지 않고 문제없이 작동합니다.

재미있는 점은 주 프로그램에서 ShowValue 메서드의 인수를 변경하면 모든 이벤트가 갑자기 작동한다는 것입니다.

Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs) 
    ' works, but the Value is lost 
End Sub 

완전히 잃어버린 것이 아니기 때문에 더 좋아집니다. Sub에 중단 점을 넣으면 e라는 Value라는 속성이 있음을 알 수 있습니다.
DirectCast도 실패하지만 EventArgs를 개체에 쓰는 것이 효과가있는 것처럼 보입니다.

Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs) 
    Dim Obj As Object = e 
    MessageBox.Show(Obj.Value.ToString()) 
    End Sub 

효과가 있지만 이것이 올바른 방법이라고 생각하지 않습니다. 어떻게 dll에서 이벤트를 처리 할 때 사용자 정의 이벤트 인수 클래스를 사용할 수 있습니까?

+0

당신은 올바른 매개 변수 유형을 specifcy해야'MethodInfo = Me.GetType.GetMethod ("ShowValue"으로 희미한 방법, 새로운 유형 () {GetType (Object), DriverAssembly.GetType ("ReflectionEventDll.ValueEventArgs")})' –

+0

이것은 작동하지 않습니다. 매개 변수를 추가하고 디버거를 검사하면 메소드가 공백이되어 메소드가 발견되지 않음을 나타냅니다. 매개 변수를 생략하면 메서드가 문제없이 발견됩니다. 디버거에서 전체 메서드 이름을 볼 수도 있습니다. – kleinisfijn

+0

[this] (http://stackoverflow.com/a/4756555/2882256) 답변을 확인 했습니까? 그는'Public Sub ShowValue (ByVal 보낸 사람 Object, ByVal e As EventArgs) '를 사용하여 끝내었고 Reflection을 사용하여'Value' 속성을 가져 왔습니다. –

답변

0

나는 this answer의 도움으로 해결책에 도달했습니다. 지금이 순간 최고의 솔루션이라고 생각하고 실패 할 경우 사용 가능한 오류가 발생합니다.

dll의 코드와 메서드 바인딩이 변경되지 않지만 호출 된 메서드는 리플렉션을 사용하여 Value 속성을 가져옵니다. VB.net에 이식하는 방법은 다음과 같습니다 핸들러 방법 가져올 때

Public Sub ShowValue(ByVal sender As Object, ByVal e As EventArgs) 
    Dim ValueProperty As PropertyInfo = e.GetType().GetProperty("Value") 
    Dim Value As Integer = Convert.ToInt32(ValueProperty.GetValue(e, Nothing)) 

    MessageBox.Show(Value.ToString()) 
    End Sub 
관련 문제