Je suis mise à niveau application vb.net qui gère les événements d'un objet COM (peut-être écrit en VB6) du cadre 1.1 à WPF 2,0/3,5Code Unmanaged appelant rappel vb.net
Le code: (noms d'objet simplifié pour la brièveté)
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
L'application recevra les rappels comme prévu, mais en quelques secondes, je reçois une violation d'accès. Le code de rappel de base est similaire à la version .net 1.1 bien qu'il fonctionne parfaitement. Selon mes recherches sur l'erreur, il est causé par le garbage collector déplacer des choses autour. Comme je ne transmets aucun objet à manipuler à la DLL, je suppose que les rappels sont les problèmes. D'autres personnes ont résolu cela via un délégué avec <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
et/ou Marshal.GetFunctionPointerForDelegate.
Malheureusement, tous les exemples que j'ai trouvés sont des cas où la DLL a une sorte de méthode SetCallback (IntPtr). J'utilise WithEvents et le mot-clé Handles. Voici ma tentative (notez que j'ai supprimé le mot-clé poignées pour que je puisse utiliser 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
L'erreur que je reçois sur la ligne AddHandler est: « Value of type MyClass.ServiceMonitor_ServiceConnectionUpDelegate cannot be converted to COMOBJECT._IServiceMonitorEvents_ServiceConnectionUpEventHandler
»
Quand je souris faites passer le dessus gestionnaire de l'événement, il a une signature: subdéléguer _IServiceMonitorEvents_ServiceConnectionUpEventHandler (ByVal MonitorId As Integer, ByVal UserArg As Integer)
les signatures sont identiques, donc je ne suis pas sûr de ce que le problème est
.Question 1: Comment utiliser un délégué avec AddHandler de cette manière? Question 2: Est-ce que Marshal.GetFunctionPointerForDelegate()
doit être impliqué? Il renvoie un IntPtr mais AddHandler veut un délégué.
Merci d'avance.
Merci pour la réponse. Je peux faire ceci cependant je ne semble pas créer un délégué non managé approprié parce que j'obtiens toujours des accidents. Je travaille sur un correctif possible: J'ai supprimé le mot-clé WithEvents pour empêcher VB de «câbler» les delagates automatiquement.J'ai ensuite utilisé leur documentation C++ pour transmettre manuellement un IntPtr géré au délégué. Je laisse cette version fonctionner pendant 2 jours sans problème mais j'ai beaucoup de code désactivé en ce moment, donc je ne suis pas sûr si je suis encore sorti du bois. Je vais câbler les autres événements dont j'ai besoin et faire un test approprié. – wtjones