c++ - dynamic_cast 返回 NULL 但它不应该

标签 c++ qt plugins dynamic-cast

我有以下类层次结构:

class IStorage {
    [...]
}
Q_DECLARE_INTERFACE(IStorage, "ch.gorrion.smssender.IStorage/1.0")


class ISQLiteStorage: public IStorage { 
    Q_INTERFACES(IStorage)

    [...] 
}
Q_DECLARE_INTERFACE(ISQLiteStorage, "ch.gorrion.smssender.ISQLiteStorage/1.0")


class DASQLiteStorage: public QObject, public ISQLiteStorage {
    Q_OBJECT
    Q_INTERFACES(ISQLiteStorage)

    [...]
}

我正在使用 QT 并尝试使用 QtPlugin 创建一个插件(用于我的应用程序)。 我正在创建 DASQLiteStorage 的实例,并将此实例提供给插件中的对象:

// the next line is within my main app.
// storage is the DASQLiteStorage instance.
// gateway is an object from within the plugin.
gateway->setDefaultStorage(storage);

// this method lies within the plugin
void AbstractGateway::setDefaultStorage(IStorage* storage) {
    defaultStorage_ = dynamic_cast<ISQLiteStorage*>(storage);
}

问题是,在我的主应用程序中执行 dynamic_cast 时(即在“gateway->setDefaultStorage(storage);”之前),dynamic_cast 返回一个空指针(不是预期的)给我有效的指针(预期)。

有谁知道为什么会这样?程序是否在与插件不同的内存范围内运行?这会导致这样的问题吗?有什么解决办法吗?

非常感谢!


编辑: 我尝试了一些建议:

// this method lies within the plugin
void AbstractGateway::setDefaultStorage(IStorage* storage) {
    ISQLiteStorage* s = dynamic_cast<ISQLiteStorage*>(storage);
    s = static_cast<ISQLiteStorage*>(storage);
    s = qobject_cast<ISQLiteStorage*>((QObject*)storage);

    defaultStorage_ = s;
}

在该方法的第一行中,s 等于 NULL,在第二行中 s 包含正确的指针,在第三行中包含另一个指针。为什么这些指针不相等?
为什么我现在正在使用 dynamic_cast 仍然无法正常工作:

pluginLoader()->setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint);




编辑2: 我注意到,我在代码中进一步了解的段错误也与此有关。我有以下构造:

// The following classes are defined within the main app.
class ILoginAccount: public IAccount [...]

class AbstractAccountStroageOfficer {
public:
    AbstractAccountStroageOfficer(IAccount* account)[...]
}


// These classes are defined within my plugin and are created from within the plugin.
class BCAccount: public ILoginAccount {
public:
    BCAccount()
      : ILoginAccount(new DAAccountStorageOfficer(this))
    {};
}

class DAAccountStorageOfficer: public AbstractAccountStorageOfficer {
public:
    DAAccountStorageOfficer(ILoginAccount* account)
      : AbstractAccountStorageOfficer(account) // This line raises a segfault.
    {
        IAccount* a = account; // This line raises a segfault as well.
        a = dynamic_cast<IAccount*>(account); // This as well.
        a = static_cast<IAccount*>(account); // This as well.
    }
}

这些段错误不应该发生,不是吗?但他们为什么这样做?

最佳答案

基本上,RTTI 跨模块边界是不可靠的。不同的编译器在这里有不同的行为;您必须研究您的编译器/版本在这种情况下的行为方式。当然,如果您的主应用程序和插件有不同的编译器/版本,它显然没有工作的机会。

使用 static_cast 作为解决方法。

关于c++ - dynamic_cast 返回 NULL 但它不应该,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1964746/

相关文章:

c++ - 有什么方法可以让 Enter/LeaveCriticalSection 留下句柄

c++ - 在框架上用opencv绘制一个矩形

c++ - 基于文件路径/名称创建 QTreeWidget 目录?

c++ - QByteArray indexOf 已弃用?

plugins - 为什么 'dokku plugins-install' 不能按预期工作?

ios - phonegap 从 settings.bundle ios 获取值

java - 列出所有可用的 ResourceBundle 文件

c++ - x86 架构中的指令解码

c++ - 将文本和二进制数据连接到一个文件中

c++ - 在qml中显示、更改数据并保留QQmlListProperty