如何将C#DLL中的AddHandler转换为VB Proj

时间:2016-11-27 17:37:47

标签: c# vb.net dll addhandler

有人知道从C#DLL到VB App的添加处理程序。当我尝试将AddHandler用于我的VB项目时,Visual Studio返回:

Error   BC30676 'DebugMessageEvent' is not an event of 'Debugger'...

Debugger.Instance.DebugMessageEvent是一个名为DLLNAMESPACE的DLL的一部分,它有自己的类Debugger,并从DLL中的其他类发送有关其他方法和进程的信息,名为DLLNAMESPACE

enter image description here

如果我去了DebugMessageEvent' VB Proj的定义(从DLL中自动转换为DLLNAMESPACE),我得到以下代码:

Public Class Debugger
    Public DebugMessageEvent As EventHandler(Of DebugMessageArgs)

    Public Shared ReadOnly Property Instance As Debugger

    Public Class DebugMessageArgs
        Inherits EventArgs

        Public Sub New()

        Public Property Message As Object
    End Class
End Class

VB项目(没有工作)

Imports DLLNAMESPACE
Public Class myclass
    ...
    Private Sub backup(...)
        AddHandler Debugger.Instance.DebugMessageEvent, AddressOf console_DebugMessageEvent
        ...
    End Sub
    ...
    Private Sub console_DebugMessageEvent(sender As Object, e As Debugger.DebugMessageArgs)
        Console.WriteLine(e.Message)
    End Sub
    ...
End Class

另一个C#项目(作品)

using DLLNAMESPACE;
public partial class myclass : Form
{
    ...
    private void backup()
    {
        Debugger.Instance.DebugMessageEvent += console_DebugMessageEvent;
        ...
    }
    ...

    void console_DebugMessageEvent(object sender, Debugger.DebugMessageArgs e)
    {
        Console.WriteLine(e.Message);
    }
    ...
}

enter image description here

DLL C#代码

using System;
namespace DLLNAMESPACE
{
    public sealed class Debugger
    {
        private static readonly Lazy<Debugger> instance = new Lazy<Debugger>(() => new Debugger());

        private Debugger()
        {

        }

        public static Debugger Instance
        {
            get { return instance.Value; }
        }

        public EventHandler<DebugMessageArgs> DebugMessageEvent;

        public class DebugMessageArgs : EventArgs
        {
            public object Message { get; set; }
        }

        private void RaiseDebugMessageEvent(object message)
        {
            DebugMessageEvent?.Invoke(this, new DebugMessageArgs
            {
                Message = message
            });
        }

        internal void DebugMessage(object data)
        {
            RaiseDebugMessageEvent(data);
        }
    }
}

所有其余的DLL函数都按预期工作。请指教,我不想更改DLL的代码,只需要修改VB.NET代码

一些不成功的测试

通过Visual Studio验证,但与DLLNAMESPACE关联的其他后台进程将关闭。

新的EventHandler

Imports DLLNAMESPACE
Public Class myclass
    ...
    Private Sub backup(...)
        Debugger.Instance.DebugMessageEvent = New EventHandler(Of Debugger.DebugMessageArgs)(AddressOf console_DebugMessageEvent)
        ...
    End Sub
    ...
    Private Sub console_DebugMessageEvent(sender As Object, e As Debugger.DebugMessageArgs)
        Console.WriteLine("Consola RoboSharp: " & e.Message)
    End Sub
    ...
End Class

DirectCast

Imports DLLNAMESPACE
Public Class myclass
    ...
    Private Sub backup(...)
        Debugger.Instance.DebugMessageEvent = DirectCast(System.Delegate.Combine(Debugger.Instance.DebugMessageEvent, DirectCast(AddressOf console_DebugMessageEvent, EventHandler(Of Debugger.DebugMessageArgs))), EventHandler(Of Debugger.DebugMessageArgs))
        ...
    End Sub
    ...
    Private Sub console_DebugMessageEvent(sender As Object, e As Debugger.DebugMessageArgs)
        Console.WriteLine("Consola RoboSharp: " & e.Message)
    End Sub
    ...
End Class

如果有人有时间重新创建我的问题,请尝试使用nuget中的robosharp并将其添加到您的vb.net项目中

2 个答案:

答案 0 :(得分:1)

'DebugMessageEvent'不是一个事件,所以你不能用'AddHandler'来处理它。它是委托类型的字段,因此您可以使用以下内容:

Debugger.Instance.DebugMessageEvent = DirectCast(System.Delegate.Combine(Debugger.Instance.DebugMessageEvent, DebugMessage), EventHandler(Of DebugMessageArgs))

答案 1 :(得分:0)

如果using System; namespace DebuggerHelperDLL { public static class DebuggerHelper { public static void AddHandler(EventHandler<Debugger.DebugMessageArgs> eventHandler) { Debugger.Instance.DebugMessageEvent += eventHandler; } } } 解决方案导致其他使用DLL的应用程序崩溃,我认为最好的解决方案是创建一个C#DLL来为您添加处理程序。

例如:

DebuggerHelper.AddHandler(AddressOf console_DebugMessageEvent)

然后在你的VB.NET项目中:

+=

虽然它不起作用似乎很奇怪,因为使用.method public hidebysig static void AddHandler ( class [mscorlib]System.EventHandler`1<class DLLNAMESPACE.Debugger/DebugMessageArgs> eventHandler ) cil managed { // Method begins at RVA 0x211c // Code size 29 (0x1d) .maxstack 8 IL_0000: nop IL_0001: call class DLLNAMESPACE.Debugger DLLNAMESPACE.Debugger::get_Instance() IL_0006: dup IL_0007: ldfld class [mscorlib]System.EventHandler`1<class DLLNAMESPACE.Debugger/DebugMessageArgs> DLLNAMESPACE.Debugger::DebugMessageEvent IL_000c: ldarg.0 IL_000d: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) IL_0012: castclass class [mscorlib]System.EventHandler`1<class DLLNAMESPACE.Debugger/DebugMessageArgs> IL_0017: stfld class [mscorlib]System.EventHandler`1<class DLLNAMESPACE.Debugger/DebugMessageArgs> DLLNAMESPACE.Debugger::DebugMessageEvent IL_001c: ret } // end of method DebuggerHelper::AddHandler 运算符编译的C#DLL在反编译成IL时产生了这个:

IL_000d

正如您在偏移System.Delegate::Combine()上看到的那样,它会调用call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)

{{1}}