2009-07-09 165 views
2

我升级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想要一个委托。

在此先感谢。

回答

0

虽然我敢肯定没有100%的问题是固定的,到目前为止,我还没有得到任何更多的访问冲突。

基本上我删除了WithEvents关键字,以防止VB使用自己的COM - > .net错误处理,而是使用C++客户端库中的方法。我使用了<UnmanagedFunctionPointer(CallingConvention.Cdecl)>并通过了库Marshal.GetFunctionPointerForDelegate IntPtr。尽管它可能已经过时,但我还保留了对IntPtr的参考。

我很困惑,自从WithEvents处理程序在.net 1.1中完美工作以来,我不得不经历所有这些。主要的区别在于我使用表单来处理回调而不是类。

一个悬而未决的问题是调试器有时会在我关闭应用程序窗体时保持运行。我希望这只是一个调试器怪癖。

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 
+0

感谢您的回复。我可以做到这一点,但我似乎没有创建一个适当的非托管代理,因为我仍然崩溃。 我正在努力解决一个可能的问题:我删除了WithEvents关键字,以防止VB自动“布线”这些延迟。然后,我使用他们的C++文档手动将托管的IntPtr传递给委托。 我让这个版本运行2天没有问题,但我现在有很多代码被禁用,所以我不知道我是否还没有走出困境。我会把我需要的其他事件联系起来并做适当的测试。 – wtjones 2009-07-12 18:54:39

相关问题