dynamic_cast返回NULL,但它不应该 [英] dynamic_cast returns NULL but it shouldn't

查看:1878
本文介绍了dynamic_cast返回NULL,但它不应该的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类层次结构:

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


类ISQLiteStorage:public IStorage {
Q_INTERFACES(IStorage)

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


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

[...]
}

我正在使用QT,我想用QtPlugin创建一个插件(对于我的应用程序)。
我创建一个DASQLiteStorage的实例,我给这个实例从一个对象FROM WITHIN插件:

  /下一行是在我的主要应用程序。 
// storage是DASQLiteStorage实例。
// gateway是插件中的一个对象。
gateway-> setDefaultStorage(storage);

//此方法位于插件内
void AbstractGateway :: setDefaultStorage(IStorage * storage){
defaultStorage_ = dynamic_cast< ISQLiteStorage *>(storage);问题是,dynamic_cast返回一个空指针(不是一个空指针)预期),而在我的主应用程序(即在gateway-> setDefaultStorage(storage);)之前做dynamic_cast给我有效的指针(预期)。



任何人都知道为什么会发生这种情况?程序是否在与插件不同的内存范围内运行?这会导致这样的问题吗?任何想法如何解决这个问题?



非常感谢!







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

  //此方法位于插件内
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,包含正确的指针,并在第三个其他指针。为什么这些指针不相等?

为什么我现在使用dynamic_cast仍然不工作:

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







编辑2:
我注意到,分段错误我得到一点进一步的代码也与此相关。我有以下结构:

  //以下类在主应用程序中定义。 
class ILoginAccount:public IAccount [...]

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


//这些类在我的插件中定义,并从插件中创建。
类BCAccount:public ILoginAccount {
public:
BCAccount()
:ILoginAccount(new DAAccountStorageOfficer(this))
{};
}

class DAAccountStorageOfficer:public AbstractAccountStorageOfficer {
public:
DAAccountStorageOfficer(ILoginAccount * account)
:AbstractAccountStorageOfficer segfault。
{
IAccount * a = account; //这行也引发一个segfault。
a = dynamic_cast< IAccount *>(account); //这也是。
a = static_cast< IAccount *>(account); //这也是。
}
}

这些分段错误不应该发生,

解决方案

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



使用static_cast作为一个工作。 p>

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?

解决方案

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.

这篇关于dynamic_cast返回NULL,但它不应该的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆