首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非托管代码调用vb.net回调

非托管代码调用vb.net回调
EN

Stack Overflow用户
提问于 2009-07-09 19:16:14
回答 2查看 2.4K关注 0票数 2

我正在将处理COM对象(可能是用VB6编写的)事件的vb.net应用程序从Framework1.1升级到WPF2.0/3.5

代码:(为简洁起见,简化了对象名称)

代码语言:javascript
复制
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:

代码语言:javascript
复制
<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需要一个委托。

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-07-20 16:11:42

虽然我还不能100%确定这个问题已经解决了,但到目前为止我还没有遇到任何访问冲突。

基本上,我删除了WithEvents关键字,以防止VB使用自己的COM -> .net错误处理,而是使用用于C++客户端的库中的方法。我使用了<UnmanagedFunctionPointer(CallingConvention.Cdecl)>并向库传递了一个Marshal.GetFunctionPointerForDelegate IntPtr。我还保留了对IntPtr的引用,尽管它可能被夸大了。

我很困惑,因为WithEvents处理程序在.net 1.1中工作得很好,所以我不得不经历这一切。主要区别在于我使用窗体而不是类来处理回调。

一个挥之不去的问题是,当我关闭应用程序窗体时,调试器有时会保持运行。我希望这只是一个调试器的怪癖。

票数 0
EN

Stack Overflow用户

发布于 2009-07-12 09:21:51

尝试将您的委托声明为预期的委托类:

代码语言:javascript
复制
   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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1105926

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档