Я обновлении vb.net приложение, которое обрабатывает события СОМ-объекта (возможно, написан в VB6) из рамок 1.1 в 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
»
Когда я мышь парить упомянутый Обработчик событий имеет подпись: делегат Sub _IServiceMonitorEvents_ServiceConnectionUpEventHandler (ByVal MonitorId As Integer, ByVal UserArg As Integer)
подписи идентичны, так что я не уверен, что проблема
.Вопрос 1: Как использовать делегат с AddHandler таким образом? Вопрос 2: Нужно ли принимать участие Marshal.GetFunctionPointerForDelegate()
? Он возвращает IntPtr, но AddHandler хочет делегата.
Заранее спасибо.
Спасибо за ответ. Я могу это сделать, однако, похоже, я не создаю должного неуправляемого делегата, потому что у меня все еще возникают сбои. Я работаю над возможным исправлением: я удалил ключевое слово WithEvents, чтобы не допустить, чтобы VB автоматически «подключал» delagates.Затем я использовал их документацию на C++, чтобы вручную передать управляемый IntPtr делегату. Я позволил этой версии работать в течение 2 дней без проблем, но сейчас у меня есть очень много кода, поэтому я не уверен, что я еще из леса. Я подключу другие события, которые мне нужны, и сделаю правильный тест. – wtjones