dynamic_cast une interface d’une bibliothèque partagée chargée par lt_dlopen (libtool) ne fonctionne pas

Il s’agit des fonctionnalités du plugin dans mon programme. J’ai besoin d’une classe C ++ (et d’un object) dans un plugin qui pourrait être utilisé par le module principal via une interface. L’inheritance d’interface ressemble à ceci:

typedef struct _rwd_plugin_root_t RWD_PLUGIN_ROOT_T; struct RWD_PLUGIN_API _rwd_plugin_root_t { virtual int add_ref() = 0; virtual int release() = 0; }; typedef struct _rwd_plugin_base_t RWD_PLUGIN_BASE_T; struct RWD_PLUGIN_API _rwd_plugin_base_t : _rwd_plugin_root_t { virtual RWD_PLUGIN_TYPE_T get_plugin_type() = 0; virtual const char * get_plugin_label_a() = 0; virtual const wchar_t * get_plugin_label_w() = 0; }; typedef struct _rwd_autocomplete_plugin_base_t RWD_AUTOCOMPLETE_PLUGIN_BASE_T; struct RWD_PLUGIN_API _rwd_autocomplete_plugin_base_t : _rwd_plugin_base_t { virtual int set_proxy(int type, const char * host, long port) = 0; virtual int set_term(const char * text) = 0; virtual int set_term(const wchar_t * text) = 0; virtual int get_phon(std::vector & phons) = 0; ... // omitted it's too long }; 

Ensuite, j’ai une classe dans le plugin pour implémenter l’interface comme ceci:

 class RWD_PLUGIN_API _rwd_dictcn_t : public _rwd_autocomplete_plugin_base_t { public: _rwd_dictcn_t(); ~_rwd_dictcn_t(); ... // details of implementation omitted 

Le créateur du plugin est défini comme suit:

 EXTERN_C int RWD_PLUGIN_API create_rwd_plugin(_rwd_plugin_base_t ** pp) { *pp = new _rwd_dictcn_t(); return OK; } 

Enfin, j’utilise le créateur dans l’application principale pour utiliser le plugin comme ceci:

 ... lt_dlhandle lh = lt_dlopen(filePath); RWD_PLUGIN_CREATE_FUNC_T pPluginFunc = NULL; if(lh) { pPluginFunc = reinterpret_cast(lt_dlsym(lh, "create_rwd_plugin")); if(pPluginFunc) { RWD_PLUGIN_BASE_T * pBase = NULL; if(OK == (*pPluginFunc)(&pBase)) { RWD_PLUGIN_TYPE_T pluginType = pBase->get_plugin_type(); if(pluginType == RWD_PLUGIN_TYPE_AUTOCOMPELE) { ... RWD_PLUGIN_FUNC_T pPluginInitFunc = reinterpret_cast(lt_dlsym(lh, "initialize_rwd_plugin")); if(pPluginInitFunc) (*pPluginInitFunc)(NULL); // set proxy RWD_AUTOCOMPLETE_PLUGIN_BASE_T * pAuto = dynamic_cast(pBase); ... 

Le problème est que dynamic_cast échoue toujours et que pAuto finit par être nul. Cependant, la version WIN32 fonctionne bien. Le problème est survenu sous Linux avec autoconf2.61 automake1.10.1 make3.81 g ++ 4.4.4 libtool1.5.26. J’ai moins d’expérience avec la programmation Linux et j’espère obtenir de l’aide ici. Merci!

Le code source complet peut être obtenu sur Sourceforge si nécessaire: svn co https://rdwtwdb.svn.sourceforge.net/svnroot/rdwtwdb rdwtwdb

vous pouvez essayer de construire avec l’ -Wl,--export-dynamic linker. Je me souviens d’avoir eu besoin de cet argument lorsque je rencontrais un comportement similaire.

Votre problème peut être l’inheritance privé:

_rwd_autocomplete_plugin_base_t : _rwd_plugin_base_t

Aussi, je pense que parce que vous avez des fonctions virtuelles, vos types sont déjà polymorphes, mais il ne serait pas plus mal d’append des destructeurs virtuels.

Edit : Désolé, vous venez de réaliser que vous utilisez struct ici, donc l’inheritance par défaut est public. Mais il vaut probablement mieux être explicite, d’autant plus que vous constatez des différences entre les compilateurs.