2010-12-08 34 views
0

J'écris une application qui utilise libwireshark, bien que les détails ne sont pas entièrement pertinents ici.Enveloppant l'appelant/callbacks dans une seule fonction

Je prépare un paquet pour la bibliothèque à disséquer et appelle donc epan_dissect_run(packet), qui à son tour dissèque le paquet donné et appelle donc une fonction de rappel que j'ai spécifiée - en utilisant register_tap_listener().

Ma question est: comment puis-je envelopper ce processus dans une seule fonction, dissected_information* MyDissectPacket(packet)? Cela s'applique non seulement à libwireshark comme je l'ai souligné, mais aux bibliothèques qui font un usage judicieux des rappels en général. La réponse dépend-elle du fait que le rappel est exécuté de manière asynchrone, sur un autre thread ou sur les 2? Si le callback est exécuté de façon synchrone sur le même thread, cela rend-il le code de retour plus simple?

Peut-être que c'est mon Google-fu qui est faible - je ne sais pas quels termes je devrais utiliser, car cette question a sûrement été posée plusieurs fois auparavant.

Répondre

1

Si vous n'avez aucune idée si elle est asynchrone ou non, vous devriez écrire votre fonction comme si c'était le cas. C'est un problème de producteur/consommateur: y a-t-il quelque chose à consommer - le paquet est-il disséqué? Ainsi, les sémaphores peuvent le résoudre pour attendre qu'il y ait quelque chose à consommer. Votre fonction de rappel doit signaler que la dissection du paquet est terminée - il y a quelque chose à consommer.

Et ce que je ferais est (code de pseudo):

void my_callback() 
{ 
    semaphore.post() 
} 

// ... 

dissected_information* MyDissectPacket(packet) 
{ 
    epan_dissect_run(packet) // asynchronous or not call 
    semaphore.wait()   // if it is, it will stop here and wait the post() of the 
          // callback 
          // if it is not, it will result exaclty like above, but the 
          // semaphore will always be already "posted"; so you will just have 
          // a useless semaphore. 
} 

J'espère que je comprends bien votre problème ...

EDIT: En cas de vous obtenir votre résultat par la callback:

void my_callback(result) 
{ 
    shared_var_result = result; 
    semaphore.post() 
} 

// ... 

dissected_information* MyDissectPacket(packet) 
{ 
    epan_dissect_run(packet) // asynchronous or not call 
    semaphore.wait()   // if it is, it will stop here and wait the post() of the 
          // callback 
          // if it is not, it will result exaclty like above, but the 
          // semaphore will always be already "posted"; so you will just have 
          // a useless semaphore. 
    return shared_var_result 
} 

Je ne vois pas d'autre solution raisonnable.

+0

Dans ce cas particulier, le travail est effectué de manière synchrone. Je suppose que ce que je cherche est un moyen d'accéder aux résultats de la dissection à partir de la fonction qui a appelé la routine de dissection. Je sais que cela pourrait être fait en utilisant des variables globales, mais sûrement il doit y avoir un meilleur moyen? –

+0

qui retourne le résultat? –