2017-09-08 1 views
-2

Comment puis-je appeler une méthode d'un objet connaissant l'adresse de l'objet et l'adresse de la méthode (et sa signature):appeler une fonction membre C++ en utilisant l'adresse de l'objet et l'adresse de la méthode et la signature

auto x = (int(*)())(&A::get_state) 

Soit l'objet x de type void*.

Ainsi, en utilisant x et m, x de type void* et m de type int(*)()

+1

Montrez votre tentative complète et quelle ligne vous donne une erreur. Astuce: vous devez d'abord lancer le pointeur d'objet sur le bon type, si c'est «void *» (je n'ai aucune idée de ce qui est maintenant car vos variables sont toutes des lettres simples non descriptives). –

+1

'&& :: get_state' n'est probablement pas' int (*)() 'mais' int (A :: *)() const'. – Jarod42

+0

Il n'y a pas de tentative parce que je ne sais pas comment je devrais faire cela. Je ne peux pas passer le paramètre d'objet à la méthode, je ne peux pas faire x-> m parce que x est de type void * – yonutix

Répondre

1

Puisque la question est tout à fait clair, je ne devine aveuglément ce que vous essayez de faire et de donner une brève explication de la façon de faire cette. En règle générale, les mécanismes de plug-in utilisant des bibliothèques partagées/dynamiques sont implémentés de sorte que vous ayez une interface.

class IPlugin 
{ 
    virtual int doSomething() = 0; 
}; 

Ensuite, vous implémenter cette interface dans votre bibliothèque et, en outre, fournir une fonction C pour créer une instance de la classe de mise en œuvre (fonction C, car ils ne sont pas nommer mutilées).

class MyPlugin : public IPlugin 
{ 
    int doSomething() override { /* ... */ } 
}; 

extern "C" 
{ 
    IPlugin* createPlugin() 
    { 
     return new MyPlugin{}; 
    } 
} 

Maintenant, dans votre application vous chargez la bibliothèque à l'aide dlopen (ou LoadLibrary sous Windows) et allez chercher l'adresse de votre fonction createPlugin à l'aide dlsym (ou GetProcAddress):

void* addr = dlsym(handle, "createPlugin"); 

Ensuite, vous lancez ceci au type réel, ce qui est équivalent dans toutes les bibliothèques:

auto createPlugin = reinterpret_cast<IPlugin*(*)()>(addr); 

en appelant createPlugin vous pouvez maintenant créer une instance de votre implémentation concrète et y accéder via l'interface. Il n'est pas nécessaire d'extraire d'autres méthodes, puisque les fonctions membres virtual peuvent être appelées directement à travers les limites de la bibliothèque (à cause de la vtable).

IPlugin* plugin = createPlugin(); 
int result = plugin->doSomething(); 

Même chose pour les fonctions avec des arguments et différents types de retour, bien sûr. Vous devez cependant exporter une autre fonction C pour détruire à nouveau l'instance d'objet. delete doit toujours être appelée par la bibliothèque qui a créé l'objet (car la bibliothèque peut avoir été créée avec une implémentation différente de new que l'exécutable).