我正在将处理 COM 对象事件的 vb.net 应用程序(可能用 VB6 编写)从框架 1.1 升级到 WPF 2.0/3.5
代码:(为简洁起见,简化了对象名称)
public class MyClass
Private WithEvents serviceMonitor As COMOBJECT.ServiceMonitor
Public Sub New()
serviceMonitor = New COMOBJECT.ServiceMonitor()
serviceMonitor.Connect([some ip address])
End Sub
Private Sub ServiceMonitor_ServiceConnectionUp(ByVal MonitorId As Integer, ByVal UserArg As Integer) _
Handles serviceMonitor.ServiceConnectionUp
Debug.WriteLine("connection up!")
End Sub
' other similar handlers omitted
End Class
该应用程序将按预期获得回调,但是在几秒钟内我收到访问冲突。基本的回调代码与.net 1.1版本类似,尽管它运行得很好。
根据我对错误的研究,这是由垃圾收集器移动东西引起的。由于我没有向 DLL 传递任何要操作的对象,因此我猜测回调是问题所在。其他人已经通过代表解决了这个问题<UnmanagedFunctionPointer(CallingConvention.Cdecl)>
和/或 Marshal.GetFunctionPointerForDelegate。
不幸的是,我发现的所有示例都是 DLL 具有某种 SetCallback(IntPtr) 方法的情况。我正在使用 WithEvents 和 Handles 关键字。这是我的尝试(请注意,我删除了 Handles 关键字,以便可以使用 AddHandler:
<UnmanagedFunctionPointer(CallingConvention.Cdecl)> _
Delegate Sub ServiceMonitor_ServiceConnectionUpDelegate(ByVal MonitorId As Integer, ByVal UserArg As Integer)
public class MyClass
Private WithEvents serviceMonitor As COMOBJECT.ServiceMonitor
Public Sub New()
serviceMonitor = New COMOBJECT.ServiceMonitor()
del = New ServiceMonitor_ServiceConnectionUpDelegate(AddressOf ServiceMonitor_ServiceConnectionUp)
AddHandler serviceMonitor.ServiceConnectionUp, del ' <--- Error here
serviceMonitor.Connect([some ip address])
End Sub
Private Sub ServiceMonitor_ServiceConnectionUp(ByVal MonitorId As Integer, ByVal UserArg As Integer)
Debug.WriteLine("connection up!")
End Sub
' other similar handlers omitted
End Class
我在 AddHandler 行遇到的错误是:“Value of type MyClass.ServiceMonitor_ServiceConnectionUpDelegate cannot be converted to COMOBJECT._IServiceMonitorEvents_ServiceConnectionUpEventHandler
"
当我将鼠标悬停在提到的事件处理程序上时,它具有以下签名:
委托子 _IServiceMonitorEvents_ServiceConnectionUpEventHandler(ByVal MonitorId 作为整数,ByVal UserArg 作为整数)
签名是相同的,所以我不确定问题是什么。
问题 1:如何以这种方式将委托与 AddHandler 一起使用?
问题2:是否Marshal.GetFunctionPointerForDelegate()
需要参与吗?它返回一个 IntPtr 但 AddHandler 需要一个委托。
提前致谢。