J'ai réussi à charger un plugin C++ en utilisant une classe de chargeur de plugins personnalisée. Chaque plugin a une fonction extern "C" create_instance qui retourne une nouvelle instance en utilisant "new".impossible d'appeler avec succès la fonction dans le plugin chargé dynamiquement en C++
Un plugin est une classe abstraite avec quelques fonctions non-virtuelles et plusieurs variables protégées (std :: vector refList en fait partie).
La classe plugin_loader charge avec succès et demande même une méthode virtuelle de la classe chargée (à savoir « std :: plugin string :: getName() ».
La fonction principale crée une instance de « hôte » qui contient un vecteur de référence a compté des pointeurs intelligents, refptr, dans la classe "plugin", puis crée une instance de plugin_loader qui fait en fait le dlopen/dlsym, et crée une instance de refptr en lui passant create_instance(). le refptr créé à la fonction addPlugin de l'hôte host :: addPlugin réussit appelle plusieurs fonctions sur l'instance du plugin passé et l'ajoute finalement à un vecteur < refptr <plugin> >.
La fonction principale s'abonne ensuite à plusieurs événements Apple et appelle RunApplicationEventLoop(). Le rappel d'événement décode le résultat et appelle ensuite une fonction dans l'hôte, host :: sendToPlugin, qui identifie le plugin auquel l'événement est destiné, puis appelle le gestionnaire dans le plugin. C'est à ce moment que les choses s'arrêtent de fonctionner. Host :: sendToPlugin lit le résultat et détermine le plugin auquel envoyer l'événement.
J'utilise un plugin extrêmement basique créé comme un plugin de débogage qui retourne des valeurs statiques pour chaque fonction non-nulle.
Tout appel sur une fonction virtuelle dans le plugin du vecteur provoque une exception d'accès incorrecte. J'ai essayé de remplacer le refptrs avec des pointeurs réguliers et aussi boost :: shared_ptrs et je reçois toujours la même exception. Je sais que l'instance du plugin est valide car je peux examiner l'instance dans le débogueur de Xcode et même voir les éléments dans la refList du plugin.
Je pense que cela pourrait être un problème de threading car les plugins ont été créés dans le thread principal pendant que le callback fonctionne dans un thread séparé.
I pense choses sont toujours en cours d'exécution dans le thread principal à en juger par le backtrace lorsque le programme rencontre l'erreur, mais je ne connais pas l'implémentation de RunApplicationEventLoop d'Apple, donc je ne peux pas être sûr.
Des idées sur les raisons pour lesquelles cela se produit?
class plugin
{
public:
virtual std::string getName();
protected:
std::vector<std::string> refList;
};
et la classe pluginloader:
template<typename T> class pluginLoader
{
public: pluginLoader(std::string path);
// initializes private mPath string with path to dylib
bool open();
// opens the dylib and looks up the createInstance function. Returns true if successful, false otherwise
T * create_instance();
// Returns a new instance of T, NULL if unsuccessful
};
class host
{
public:
addPlugin(int id, plugin * plug);
sendToPlugin(); // this is the problem method
static host * me;
private:
std::vector<plugin *> plugins; // or vector<shared_ptr<plugin> > or vector<refptr<plugin> >
};
code d'événement de pomme de host.cpp; EDIT: Il est exécuté sur OSX 10.5.8 et j'utilise GCC 4.0 avec Xcode. Ceci est pas conçu pour être une application multi-plateforme.
EDIT: Pour être clair, le plugin fonctionne jusqu'à ce que la boucle d'événement fournie par Apple appelle ma fonction de rappel. Lorsque la fonction de rappel rappelle l'hôte, les choses s'arrêtent.C'est le problème que j'ai, tout le reste fonctionne jusqu'à ce point.
Un extrait de code pourrait vous aider. –
Nommer l'OS serait également utile. Comme Apple est mentionné, je suis en train de dire que c'est le dernier Mac OS. –
il * est * os x, 10.5. Je pense que c'est plus général que cela en ce qu'il implique un rappel d'événement. Comme pour un extrait de code, plugins [id] -> getName() ;. Peu importe la méthode que j'appelle, je sais que la cible existe et j'ai été capable d'appeler des méthodes dans le thread principal. – user150113