dynamic_cast returns NULL but it shouldn't

喜你入骨 提交于 2019-12-19 19:57:55

问题


I'm having the following class hierarchy:

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)

    [...]
}

I'm using QT and am trying to create a plugin (for my app) with QtPlugin. I'm creating an instance of DASQLiteStorage and I give this instance to an object FROM WITHIN the plugin:

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

The problem is, that the dynamic_cast is returning me a null-pointer (not expected), while doing the dynamic_cast within my main app (i.e. before "gateway->setDefaultStorage(storage);") gives me the valid pointer (expected).

Does anyone know why this could happen? Is the program operating in a different memory range as the plugin? Could this lead to such problems? Any ideas how to fix this?

Thanks a lot!


EDIT: I've tried out some suggestions:

// 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;
}

In the first line of the method, s equals NULL, in the second s contains the correct pointer and in the third an other pointer. Why aren't these pointers equal?
And why could the dynamic_cast be still not working although I'm using now:

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




EDIT2: I noticed, that the segmentation fault I get a little further in the code is also related to this. I have the following construct:

// 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.
    }
}

These segmentation faults should not occur, should they? But why do they?


回答1:


Basically, RTTI is unreliable across module boundaries. Different compilers have different behaviors here; you'll have to research how your compiler/version acts in this case. Of course, if you have a different compiler/version for the main app and plugin, it clearly has no chance of working.

Use static_cast as a work around.



来源:https://stackoverflow.com/questions/1964746/dynamic-cast-returns-null-but-it-shouldnt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!