我正在将处理COM对象(可能是用VB6编写的)事件的vb.net应用程序从Framework1.1升级到WPF2.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“
当我将鼠标悬停在提到的事件处理程序上时,它的签名为: Delegate Sub _IServiceMonitorEvents_ServiceConnectionUpEventHandler(ByVal MonitorId As Integer,ByVal UserArg As Integer)
签名是相同的,所以我不确定问题出在哪里。
问题1:如何以这种方式在AddHandler中使用委托?问题2:Marshal.GetFunctionPointerForDelegate()是否需要参与?它返回一个IntPtr,但AddHandler需要一个委托。
提前谢谢。
发布于 2009-07-20 16:11:42
虽然我还不能100%确定这个问题已经解决了,但到目前为止我还没有遇到任何访问冲突。
基本上,我删除了WithEvents关键字,以防止VB使用自己的COM -> .net错误处理,而是使用用于C++客户端的库中的方法。我使用了<UnmanagedFunctionPointer(CallingConvention.Cdecl)>并向库传递了一个Marshal.GetFunctionPointerForDelegate IntPtr。我还保留了对IntPtr的引用,尽管它可能被夸大了。
我很困惑,因为WithEvents处理程序在.net 1.1中工作得很好,所以我不得不经历这一切。主要区别在于我使用窗体而不是类来处理回调。
一个挥之不去的问题是,当我关闭应用程序窗体时,调试器有时会保持运行。我希望这只是一个调试器的怪癖。
发布于 2009-07-12 09:21:51
尝试将您的委托声明为预期的委托类:
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 Subhttps://stackoverflow.com/questions/1105926
复制相似问题