我升级vb.net的应用程序,处理从框架1.1的COM对象(可能写在VB6)至WPF 2.0/3.5非托管代码调用回调vb.net
的事件的代码:(对象名称简化为简洁起见)
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想要一个委托。
在此先感谢。
感谢您的回复。我可以做到这一点,但我似乎没有创建一个适当的非托管代理,因为我仍然崩溃。 我正在努力解决一个可能的问题:我删除了WithEvents关键字,以防止VB自动“布线”这些延迟。然后,我使用他们的C++文档手动将托管的IntPtr传递给委托。 我让这个版本运行2天没有问题,但我现在有很多代码被禁用,所以我不知道我是否还没有走出困境。我会把我需要的其他事件联系起来并做适当的测试。 – wtjones 2009-07-12 18:54:39