【发布时间】:2011-12-21 17:59:37
【问题描述】:
我有一个 .NET 接口
<System.Runtime.InteropServices.GuidAttribute("0896D946-8A8B-4E7D-9D0D-BB29A52B5D08"), _
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface IEventHandler
Sub OnEvent(ByRef sender As Object, ByRef e As Object)
End Interface
在导出的类型库中。
VB6 代码引用了这个 tlb 并实现了这个接口。
VB6 代码创建其实现的实例并将其传递给 .NET。
.NET 调用 OnEvent。
VB6 可以很好地接收事件...但是 sender 和 e 参数值是字符串,而不是当它到达那里时的对象...字符串值是类型的全名...
VB6 代码:
Implements Interop.IEventHandler
Private Sub IEventHandler_OnEvent(ByRef sender As Variant, ByRef e As Variant)
Dim id
id = e.Person.Id
' The weird thing here:
' e = "XYZ.Tasks.PersonTaskEventArgs"
' sender = "XYZ.Tasks.PersonUIManager"
' The values of the arguments are the NAMEs of the actual object values' types...
End Sub
触发事件的代码相当简单。我有一个带有字典的 COM 类,它注册处理程序并触发事件。
<ComClass(ComRegistrar.ClassId, ComRegistrar.InterfaceId, ComRegistrar.EventsId>
Public Class ComRegistrar
Private Shared ReadOnly _eventHandlers As New Dictionary(Of String, List(Of IEventHandler))
' This is called by .NET code to fire events to VB6
Public Shared Sub FireEvent(ByVal eventName As String, ByVal sender As Object, ByVal e As Object)
For Each eventHandler In _eventHandlers(eventName)
eventHandler.OnEvent(sender, e)
Next
End Sub
Public Sub RegisterHandler(ByVal eventName As String, ByVal handler As IEventHandler)
Dim handlers as List(Of IEventHandler)
If Not _eventHandlers.TryGetValue(eventName, handlers)
handlers = New List(Of IEventHandler)
_eventHandlers(eventName) = handlers
End If
handlers.Add(handler)
End Sub
End Class
.NET 代码看起来像
Public Class PersonEventArgs
Inherits System.EventArgs
' Some properties
End Class
Public Class MyControl
Inherits UserControl
' Stuff
End Class
ComRegistrar.FireEvent("PersonSelected", Me, New PersonEventArgs With { Some stuff })
如果我使用实现 IEventHandler 的 .NET 类连接相同的代码,则参数可以毫无问题地通过。
更新:如果我将 OnEvent 的 ByRef 参数更改为 ByVal,则没有区别。我确定我要传递的两种类型来自标记为 ComVisible 的程序集。
这里出了什么问题?
【问题讨论】:
-
您没有发布调用 OnEvent 并传递参数值的代码。比较相关。您还必须确保通过参数公开的类是 ComVisible。
-
另请注意,COM 互操作可以公开 VB 可以订阅的“真实”COM 事件。
-
哎呀,你真的打算发送那些对象参数 ByRef 吗?
-
@Hans:是的,它们都是 ComVisible。将使用调用代码进行更新。
-
@Deanna:我知道,但我不是粉丝。
标签: .net vb6 interop com-interop