Mat*_*don 6 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);
}
Run Code Online (Sandbox Code Playgroud)
程序集使用强名称密钥签名并设置AssemblyInfo.cs了[assembly: ComVisible(true)]属性,但我不确定它与问题有什么关系.
当我看到在VB6对象浏览器,我会期待看到DoSomething(string)其中的一名成员MyClass,和我做的,但是我也看到具有匹配签名事件,每暴露方法,像Event DoSomething(someParam As String)其中的一名成员MyClass.
更令人费解的是(至少对我而言),属性也有一个"匹配"事件(虽然只能从小闪电图标中看出) - 如果MyClass定义了这样的属性:
public string SomeProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)
VB6对象浏览器会将"事件"定义为Property SomeProperty As String,这让我大吃一惊 - "属性"1)如何重复; 2)副本是否在对象浏览器中显示"事件"图标?这同样适用于只读属性,它们具有只读的"属性/事件"对应物.
这些事件来自哪里,如何摆脱它们?
更新图像胜过千言万语:

UPDATE的错误的事情是ComSourceInterfaces这是错误地被代替的使用属性ComDefaultInterface的属性.将前者换成后者会得到预期的结果:

通过将typeof(IMyClass)参数作为参数传递给ComSourceInterface属性,您会说IMyClass中的所有内容都是一个事件.
如果您不希望类的事件接口删除ComSourceInterface属性.
如果您确实要将C#类中的事件公开给VB,请执行以下操作:
当您创建COM可见类时,您还需要创建一个仅为您的类定义事件处理程序的接口.您的类应使用指定事件处理程序接口的COMSourceInterface进行修饰,并应定义事件并实现事件处理程序接口.有关其他示例,请参见如何:提升COM接收器处理的事件.
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
您基本上发现COM中的事件没有任何特殊之处.与COM中的任何内容一样,事件由接口支持.对于指定事件方法的接口,唯一特别之处在于它在类型库中使用[source]属性进行标记.这就是[ComSourceInterfaces]属性所做的一切,Tlbexp.exe在生成类型库时会识别它.
COM中的属性也没有什么特别之处.它们就像在.NET中一样工作,它们是用方法实现的.一个getter和一个setter方法.
因此,VB6会查看您的类型库,并且对具有事件的类感到高兴,因为它具有[source]属性的接口.并且对于具有方法的接口感到高兴,他们可以拥有它们,因此它假定这些是在引发事件时运行的方法.知道那些方法也是属性的访问器是不够智能的,它假定类型库作者知道他在做什么.
事件在COM中称为"连接点".谷歌IConnectionPoint了解更多信息.如果您使用自定义事件访问器创建WinRT组件,那么您还将看到COM事件与.NET事件几乎没有共同之处.
Anyhoo,解决方法很简单,只在引发事件时使用[ComSourceInterface].
| 归档时间: |
|
| 查看次数: |
1484 次 |
| 最近记录: |