Это о функциях плагинов в моей программе.Мне нужен класс C ++ (и объект) в плагине, который может использоваться основным модулем через интерфейс.Наследование интерфейса выглядит следующим образом:
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<std::string> & phons) = 0;
... // omitted it's too long
};
Затем у меня есть плагин для реализации интерфейса, подобный этому:
class RWD_PLUGIN_API _rwd_dictcn_t : public _rwd_autocomplete_plugin_base_t
{
public:
_rwd_dictcn_t();
~_rwd_dictcn_t();
... // details of implementation omitted
Создатель в плагине определяется следующим образом:
EXTERN_C int RWD_PLUGIN_API create_rwd_plugin(_rwd_plugin_base_t ** pp)
{
*pp = new _rwd_dictcn_t();
return OK;
}
Наконец, я использую создателя в основном приложении, чтобы использовать плагин, подобный этому:
...
lt_dlhandle lh = lt_dlopen(filePath);
RWD_PLUGIN_CREATE_FUNC_T pPluginFunc = NULL;
if(lh)
{
pPluginFunc = reinterpret_cast<RWD_PLUGIN_CREATE_FUNC_T>(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<RWD_PLUGIN_FUNC_T>(lt_dlsym(lh, "initialize_rwd_plugin"));
if(pPluginInitFunc)
(*pPluginInitFunc)(NULL);
// set proxy
RWD_AUTOCOMPLETE_PLUGIN_BASE_T * pAuto = dynamic_cast<RWD_AUTOCOMPLETE_PLUGIN_BASE_T*>(pBase);
...
Проблема в том, что dynamic_cast всегда терпит неудачу, и pAuto в конечном итоге становится нулевым.Однако версия WIN32 работает нормально.Проблема возникла в Linux с autoconf2.61 automake1.10.1 make3.81 g ++ 4.4.4 libtool1.5.26.У меня меньше опыта в программировании на Linux, и я надеюсь получить помощь здесь.Спасибо!
Полный исходный код можно получить на Sourceforge при необходимости: svn co https://rdwtwdb.svn.sourceforge.net/svnroot/rdwtwdb rdwtwdb