C++ 动态"从共享库强制转换接口,该库由lt"dlopen(libtool)加载&"x27 ;;行不通

C++ 动态"从共享库强制转换接口,该库由lt"dlopen(libtool)加载&"x27 ;;行不通,c++,libtool,C++,Libtool,这是关于我的程序中的插件功能。在插件中,我需要一个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_b

这是关于我的程序中的插件功能。在插件中,我需要一个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);

...
插件中的创建者定义如下:

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);

...
最后,我在主应用程序中使用creator,以便使用如下插件:

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);

...
。。。
lt_dlhandle lh=lt_dlopen(文件路径);
RWD_PLUGIN_CREATE_FUNC_T pPluginFunc=NULL;
中频(左)
{
pPluginFunc=reinterpret_cast(lt_dlsym(左侧,“创建rwd插件”);
if(pPluginFunc)
{
RWD_PLUGIN_BASE_T*pBase=NULL;
if(OK==(*pPluginFunc)(&pBase))
{
RWD_PLUGIN_TYPE_T pluginType=pBase->get_PLUGIN_TYPE();
if(pluginType==RWD\u PLUGIN\u TYPE\u autocompile)
{
...
RWD_PLUGIN_FUNC_T pPluginInitFunc=reinterpret_cast(左,“初始化RWD_插件”);
if(pPluginInitFunc)
(*pPluginInitFunc)(空);
//设置代理
RWD_AUTOCOMPLETE_PLUGIN_BASE_T*pAuto=dynamic_cast(pBase);
...
问题是动态_cast总是失败,而且pau最终可能是零。 但是,WIN32版本工作正常。 这个问题发生在linux上的autoconf2.61 automake1.10.1 make3.81 g++4.4.4 libtool1.5.26。 我对linux编程的经验较少,希望能在这里得到帮助。谢谢

如有必要,可在Sourceforge上获取完整的源代码:
svn co rdwtwdb

您遇到的问题可能是私有继承:

\u rwd\u autocomplete\u plugin\u base\u t:\u rwd\u plugin\u base\u t

我还认为,因为您有虚拟函数,所以您的类型已经是多态的,但添加虚拟析构函数不会有什么坏处


编辑:很抱歉,您刚刚意识到您在那里使用的是
struct
,因此默认继承是公共的。但最好是明确的,尤其是因为您看到编译器之间的差异。

您可以尝试使用
-Wl,--export-dynamic
链接器参数进行构建。我记得遇到此参数时需要此参数类似的行为。

Linux需要一些调整,才能使RTTI相关的东西跨共享模块边界工作。您已经阅读了吗?在bin_LDFLAGS中使用-Wl,-E解决了这个问题,非常感谢!