我正在升级vb.net应用程序,它处理从框架1.1到WPF 2.0 / 3.5的COM对象(可能用VB6编写)的事件
代码:(为简洁起见,简化了对象名称)
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
”
当我将鼠标悬停在上面提到的事件处理程序时,它有一个签名: 委托Sub _IServiceMonitorEvents_ServiceConnectionUpEventHandler(ByVal MonitorId As Integer,ByVal UserArg As Integer)
签名完全相同,所以我不确定问题是什么。
问题1:如何以这种方式使用AddHandler代理?
问题2:Marshal.GetFunctionPointerForDelegate()
是否需要参与?它返回一个IntPtr,但AddHandler想要一个委托。
提前致谢。
答案 0 :(得分:1)
尝试将您的委托声明为期望的委托类:
Public Sub New()
serviceMonitor = New COMOBJECT.ServiceMonitor()
del = New COMOBJECT._IServiceMonitorEvents_ServiceConnectionUpEventHandler(AddressOf ServiceMonitor_ServiceConnectionUp)
AddHandler serviceMonitor.ServiceConnectionUp, del
serviceMonitor.Connect([some ip address])
End Sub
答案 1 :(得分:0)
虽然我尚未100%确定该问题已得到解决,但到目前为止我还没有违反任何访问权限。
基本上我删除了WithEvents关键字以防止VB使用自己的COM - &gt; .net错误处理,而是使用用于C ++客户端的库中的方法。我使用了<UnmanagedFunctionPointer(CallingConvention.Cdecl)>
并将库Marshal.GetFunctionPointerForDelegate
IntPtr传递给了库。我也提到了IntPtr,虽然它可能有点矫枉过正。
我很困惑,因为WithEvents处理程序在.net 1.1中完美运行,所以我必须完成所有这些操作。主要区别在于我使用表单来处理回调而不是类。
一个挥之不去的问题是,当我关闭应用程序表单时,调试器有时会保持运行。我希望它只是一个调试器怪癖。