2010-08-13 7 views
0

J'ai une fonction, singleFrameEventHandler, que je souhaite appeler lorsqu'un événement donné, OnNewFrame, se produit. Après quelques recherches, il m'a semblé que les fonctions qui gèrent les événements ont un type de retour void et prennent un paramètre du type qui contient l'événement. D'après ce que je pouvais trouver en ligne, ce qui se fait comme ceci:Gestion des événements en C++/CLI

déclaration de fonction:

void singleFrameEventHandler(IAFrame^frame); 

Lorsque la fonction est assignée à gérer l'événement:

iaframe->OnNewFrame += &singleFrameEventHandler; 

Lorsque je tente de compiler le code contenant les segments ci-dessus, j'obtiens l'erreur suivante:

error C2664: 'Spiricon::BeamGage::Automation::Interfaces::IAFrame::OnNewFrame::add' : cannot convert parameter 1 from 'void (__clrcall *)(Spiricon::BeamGage::Automation::Interfaces::IAFrame ^)' to 'Spiricon::BeamGage::Automation::Interfaces::newFrame ^' 
No user-defined-conversion operator available, or 
There is no context in which this conversion is possible 

Le OnNewF La rame est de type Spiricon :: BeamGage :: Automation :: Interfaces :: newFrame, qui malheureusement n'a pas de documentation au-delà d'être décrite comme "L'événement qui est appelé quand un nouveau cadre est disponible."

Dans le navigateur d'objets, je peux trouver des informations à ce sujet: (?)

public delegate newFrame: 
    public System.IAsyncResult BeginInvoke(System.AsyncCallback callback, System.Object object) 
    public System.Void EndInvoke(System.IAsyncResult result) 
    public System.Void Invoke() 
    public newFrame(System.Object object, System.IntPtr method) 

Le constructeur newFrame semble être le meilleur pari, car il semble prendre un pointeur de méthode, mais lorsque je tente pour l'utiliser comme ceci:

iaframe->OnNewFrame += gcnew newFrame(iaframe, &singleFrameEventHandler); 

Je reçois l'erreur suivante:

error C3352: 'singleFrameEventHandler' : the specified function does not match the delegate type 'void (void)' 

ce que cela signifie t Ma fonction ne doit-elle pas prendre de paramètres? Si oui, comment aurais-je des informations sur l'événement?

Répondre

2

La première syntaxe ne peut pas fonctionner, c'est le sucre de syntaxe C# que C++/CLI n'a pas.

Le problème avec le deuxième extrait est que le type de délégué ne correspond pas à la signature de votre gestionnaire d'événements. Le délégué a été déclarée comme ceci:

delegate void newFrame(); 

Vous devez changer votre signature de la méthode à:

void singleFrameEventHandler() 
{ 
    // etc.. 
} 

Comment vous êtes censé obtenir une référence au cadre n'est pas clair de vos extraits . Je devine à une propriété sur la classe.

+0

Très bien, merci. J'ai également découvert que lorsque j'obtiens un IAFrame (qui inclut également des données pour une trame individuelle en plus de l'événement) de l'usine, j'obtiens la dernière image, donc je n'ai pas besoin du gestionnaire d'événement pour avoir un objet IAFrame passé à lui. –

6

Les gestionnaires d'événements dans .NET sont généralement définis avec deux paramètres (voir MSDN)

delegate void EventHandler(object sender, EventArgs e) 

Cependant, les messages d'erreur que vous avez posté n'impliquons fortement OnNewFrame ne suit pas ce modèle et que singleFrameEventHandler devraient prendre pas de paramètres. Je suppose que les développeurs de cette API pensaient que l'événement lui-même était suffisamment d'informations, et que le gestionnaire d'événements stockerait une référence à l'IAFrame levant l'événement s'il avait besoin de l'interroger.Un code similaire à celui-ci devrait fonctionner (à noter que lors de la création du délégué de gestionnaire d'événements, vous devez faire référence à la classe posséder la méthode de gestionnaire d'événements, et non l'objet source):

class FrameEventHandlers 
{ 
public: 
    FrameEventHandlers(IAFrame^frame) 
     : m_frame(frame) 
    { 
     m_frame->OnNewFrame += gcnew newFrame(this, &FrameEventHandlers::singleFrameEventHandler); 
    } 

private: 
    void singleFrameEventHandler() 
    { 
     // query m_frame for new data 
    } 
};