我在VB.NET中编写COM互操作DLL,我需要将事件暴露给VBA COM客户端.我无法绕过这一个. 这是.NET FTP库的COM包装器,所以不要因为我在BytesTransferred事件上引发BytesTransferred事件而感到困惑. 我最好
这是.NET FTP库的COM包装器,所以不要因为我在BytesTransferred事件上引发BytesTransferred事件而感到困惑.
我最好回想一下,这段代码可以工作,但是当我使用对象浏览器时,它无法在COM客户端中显示任何事件.当我尝试将变量WithEvents变暗时,它也无法编译:
Public Interface IFTP Event BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String) End Interface 'Here's the relevant part of my class: Public Interface IFTP Event BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String) End Interface Here's the relevant part of my class: <ClassInterface(ClassInterfaceType.None)> _ Public Class FTP : Implements IFTP Public Sub New() 'This needed for com interop End Sub Public Event BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String) Implements IFTP.BytesTransferred Private Sub fCon_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles fCon.BytesTransferred RaiseEvent BytesTransferred(e.ByteCount, e.RemoteFile) End Sub End Class
我也试过这样的东西,但我觉得我在这里遗漏了一些东西,因为它没有编译.我看到一个错误,表示我未能为接口IFTP实现Sub BytesTransferred:
Public Delegate Sub BytesTransferredDelegate(ByVal ByteCount As Long, ByVal RemoteFileName As String) Public Interface IFTP <DispId(1)> _ Sub BytesTransferred(ByVal ByteCount As Long, ByVal RemoteFileName As String) End Interface 'Here's the relevant part of my class: <ClassInterface(ClassInterfaceType.None)> _ <ProgId("MyTestClass.FTP")> _ <ComSourceInterfaces(GetType(IFTP))> _ Public Class FTP : Implements IFTP Public Event BytesTransferred As BytesTransferredDelegate Public Sub New() 'This needed for com interop End Sub Private Sub fCon_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles fCon.BytesTransferred RaiseEvent BytesTransferred(e.ByteCount, e.RemoteFile) End Sub End Class解:
1)在代码模块顶部声明Delegate Subs(带参数,如果需要)(如果你使用的话,在你的命名空间内)
2)为您的活动创建一个单独的界面,如下所示.请务必包含IDispatch声明
3)无需在主界面中为您的活动添加任何内容.
4)将ComSourceInterfaces声明与您的类声明一起使用
5)在您的课程中,使用“As”声明您的事件以指向您的Delegate Sub
如Hans Passant所述,请务必使用与VB6 / VBA兼容的数据类型. Long不是兼容的数据类型.
这是我现在的代码:
Public Delegate Sub BytesTransferredDelegate(ByVal ByteCount As Long, _ ByVal RemoteFileName As String) Public Delegate Sub OnUploaded() <InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)> _ Public Interface IFTPEvents <DispId(1)> _ Sub BytesTransferred(ByVal ByteCount As Double, _ ByVal RemoteFileName As String) <DispId(2)> _ Sub Uploaded() End Interface Public Interface IFTP 'Subs, Functions, Properties go here 'No subs, functions, or events need to be declared here 'to make our events work properly in COM End Interface <ComSourceInterfaces(GetType(IFTPEvents)), ClassInterface(ClassInterfaceType.None)> _ Public Class FTP : Implements IFTP Public Event BytesTransferred As BytesTransferredDelegate Public Event Uploaded As OnUploaded Public Sub New() 'This needed for com interop End Sub Private Sub fCon_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles fCon.BytesTransferred RaiseEvent BytesTransferred(e.ByteCount, e.RemoteFile) End Sub Private Sub fCon_Uploaded(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.FTPFileTransferEventArgs) Handles fCon.Uploaded RaiseEvent Uploaded() End Sub End Class
这是我用来解决这个问题的来源:
http://msdn.microsoft.com/en-us/library/dd8bf0x3%28v=VS.90%29.aspx
http://www.codeproject.com/KB/COM/cominterop.aspx#UnmanagedSinks
http://www.developerfusion.com/tools/convert/csharp-to-vb/