0

有人知道如何从 C# DLL 到 VB App 的 addhandlers。当我尝试在我的 VB 项目中使用 AddHandler 时,Visual Studio 会返回:

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

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

在此处输入图像描述

如果我从 VB Proj(从名为 DLLNAMESPACE 的 DLL 自动转换)转到“DebugMessageEvent”定义,我会得到以下代码:

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);
    }
    ...
}

在此处输入图像描述

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 关联的其他后台进程关闭。

新的事件处理程序

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

直播

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 项目中

4

2 回答 2

1

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

Debugger.Instance.DebugMessageEvent = DirectCast(System.Delegate.Combine(Debugger.Instance.DebugMessageEvent, DebugMessage), EventHandler(Of DebugMessageArgs))
于 2016-11-27T17:55:21.210 回答
0

如果Delegate.Combine()解决方案导致使用 DLL 的其他应用程序崩溃,在我看来,最好的解决方案是创建一个 C# DLL 来为您添加处理程序。

例如:

using System;

namespace DebuggerHelperDLL
{
    public static class DebuggerHelper
    {
        public static void AddHandler(EventHandler<Debugger.DebugMessageArgs> eventHandler)
        {
            Debugger.Instance.DebugMessageEvent += eventHandler;
        }
    }
}

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

DebuggerHelper.AddHandler(AddressOf console_DebugMessageEvent)

这似乎很奇怪,因为使用+=运算符编译的 C# DLL 在反编译为 IL 时会产生以下结果:

.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

正如您在 offset 上看到的IL_000d,它调用System.Delegate::Combine()

call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
于 2016-11-27T23:07:06.357 回答