2009-07-09 124 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

相關問題