私は次のクラス階層を持っています:
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 に等しく、2 番目の s には正しいポインターが含まれ、3 番目には別のポインターが含まれます。これらのポインターが等しくないのはなぜですか?
そして、私が現在使用しているにもかかわらず、なぜdynamic_castがまだ機能しないのですか:
pluginLoader()->setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint);
EDIT2:コードでもう少し進んだセグメンテーション違反もこれに関連していることに気付きました。私は次の構造を持っています:
// 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.
}
}
これらのセグメンテーション違反は発生すべきではありませんか? しかし、なぜ彼らはそうするのですか?