Я обновляю приложение vb.net, которое обрабатывает события COM-объекта (возможно, написанного на VB6) с платформы 1.1 до WPF 2.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
"
При наведении указателя мыши на упомянутый обработчик событий он имеет подпись:
Делегировать Sub _IServiceMonitorEvents_ServiceConnectionUpEventHandler (ByVal MonitorId как целое число, ByVal UserArg как целое число)
Подписи идентичны, поэтому я не уверен, в чем проблема.
Вопрос 1: Как использовать делегат с AddHandler таким образом?
Вопрос 2: Marshal.GetFunctionPointerForDelegate()
нужно участвовать? Он возвращает IntPtr, но AddHandler хочет получить делегата.
Заранее спасибо.