6

C++ で Qt 4.8 を使用します。実行時にロードおよびアンロードされるアプリケーション プラグインを使用しています。アプリケーションの存続期間中に、同じプラグインが複数回ロードされる場合があります。これらのプラグインの 1 つはQ_DECLARE_METATYPEQVariant. プラグインが後で再ロードされると、古い宣言はまだアンロードされたライブラリの元のメモリ空間を指しています。QVariantこれにより、Qtが再宣言されたメタ タイプからを作成しようとすると、アクセス違反が発生します。で同様の問題をすでに処理しましたqRegisterMetaType()。ライブラリがロードされたときにメタ タイプを登録し、ライブラリがアンロードされる直前にそれらのタイプを登録解除します。残念ながら、メタ タイプを登録するのではなく、宣言する場合、それはオプションではないようです。

メタ タイプを宣言するライブラリが複数回ロードおよびアンロードされるケースを効果的に処理するにはどうすればよいでしょうか?

4

2 に答える 2

1

Kuba Ober の回答を拡張するには、DLL をアンロードする前に、タイプ名でQMetaType::unregisterType()( http://doc.qt.io/qt-4.8/qmetatype.html#unregisterType ) を呼び出してメタ タイプの登録を解除する必要があります。を使用して登録したタイプを登録解除するのと同じ場所で、宣言されたメタ タイプを登録解除できるはずですqRegisterMetaType<T>。これにより、Qt メタ オブジェクト システムが (少なくともアンロードされたプラグインに関する限り) クリーンな状態のままになり、次にプラグインがロードされたときに新しいメタ タイプ ID が生成されます。具体的には、DLL が再度読み込まれると、Q_DECLARE_METATYPEマクロは型を再度登録しますが、今回は新しいmetatype_idQVariant使用するため、アクセス違反は発生しなくなります。

于 2013-10-08T19:08:46.187 に答える
1

Q_DECLARE_METATYPE の動作を見ると、静的変数を使用して の値を格納するQMetaTypeId<T>1 つのメンバーを持つのテンプレート クラスの特殊化が宣言されていることがわかります。あなたが主張するように、メタタイプの登録を解除できれば、準備は完了です。qt_metatype_id()qRegisterMetaType

于 2013-10-07T22:10:55.447 に答える