c# - VB6/COM 互操作 : where do these events come from?

标签 c# vb6 com-interop

我用 C# 4.0 编写了一个 COM 可见的类库,我正在使用 VB6。这件事有效,只有当我打开 VB6 对象浏览器 并查看公开的成员时,我看到每个公开的成员都有一个事件...但 C# 代码没有定义它们中的任何一个

这正常吗?我做错了什么吗?

[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IMyClass))]
public class MyClass : IMyClass
{
    public void DoSomething(string someParam)
    {
        ...
    }
}

public interface IMyClass
{
    void DoSomething(string someParam);
}

程序集使用强名称 key 进行签名,并且 AssemblyInfo.cs 具有 [assembly: ComVisible(true)] 属性集,但我不确定与这个问题有任何关系。

当我查看 VB6 中的对象浏览器时,我希望看到 DoSomething(string) 作为 MyClass 的成员,我确实看到了,但是我看到一个事件,每个公开的方法都有一个匹配的签名,比如 Event DoSomething(someParam As String) 作为 的成员我的类(class)

更令人费解的是(至少对我而言),属性也有一个“匹配”事件(虽然只能从小闪电图标看出)——如果 MyClass 定义了这样的属性:

public string SomeProperty { get; set; }

VB6 对象浏览器会说“事件”被定义为 Property SomeProperty As String,这让我大吃一惊 - “属性”如何 1) 被复制和 2) 显示重复项在对象浏览器中带有“事件”图标?这同样适用于只读属性,它们有只读的“属性/事件”对应物。

这些事件从何而来,我该如何摆脱它们?

更新一张图片胜过一千个字:

COM Interop - bogus events

更新 错误ComSourceInterfaces 属性被错误地用于代替 ComDefaultInterface 属性.将前者换成后者会得到预期的结果:

COM Interop - correct members

最佳答案

通过将 typeof(IMyClass) 作为参数传递给 ComSourceInterface 属性,您表示 IMyClass 中的所有内容都是一个事件。

如果您不想为您的类使用事件接口(interface),请移除 ComSourceInterface 属性。

如果您确实想要将 C# 类中的事件公开给 VB,请执行以下操作:

当您创建一个 COM 可见类时,您还需要创建一个接口(interface),该接口(interface)只为您的类定义事件处理程序。您的类应该使用指定事件处理程序接口(interface)的 COMSourceInterface 进行修饰,并且应该定义您的事件并实现事件处理程序接口(interface)。参见 How To: Raise Events Handled by a COM sink再举个例子。

[GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface MyEvents
{
    void ConnectedEvent(string state);
}


[ComSourceInterfaces(typeof(MyEvents))]
public class MyClass
{
    public event Action<string> ConnectedEvent;

    public MyClass() { }

    public void DoSomething(string state)
    { 
        if (ConnectedEvent != null)
            ConnectedEvent(state);
    }
}

另请参阅:Murat's Corner: Exposing COM Events

关于c# - VB6/COM 互操作 : where do these events come from?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16600023/

相关文章:

c# - 如何使用基类对象调用派生函数

windows - 是否有关于 IdentityUnmarshal 接口(interface)的文档?

c# - 无法访问/转换 System.Double[*] 对象

c# - C# 结构的属性在 COM 和 VB6 中获得不可用的名称?

c# - 是否可以根据其值设置组合框的selectedIndex

c# - 为 MonoGame 编译着色器

c# - 将 2 个查询的结果合并为 1 个结果,然后传递给 DGV

c# - 在 Microsoft Access VBA 中使用 .Net DLL

c# - 从多线程 c# Windows 服务应用程序调用 VB6 DLL?

vb6 - 使用 vbAccelerator Win32 Hook 与 VB IDE 一起导致应用程序崩溃