2

次のコードについて明確にする必要があります。

次のコードでは、DLL からインターフェイスのプライベート実装を取得しています。

DLL がアンロードされた後 (CASE #2)、インターフェイスから取得した文字列とインターフェイス自体が両方とも無効になり、それらにアクセスするとアクセス違反が発生します (予期されます)。

しかし、私を混乱させているのは、DLL をリロードすると、DLL から再取得せずにインターフェイスと文字列を再度使用できることです。

これはこのように機能するはずですか?

メモリが無効になり、DLL が再度読み込まれると突然再び有効になるのはなぜですか?

これは運が良かっただけで、テスト プログラムが比較的単純なため、2 回目もメモリ内のまったく同じ場所に DLL がロードされるのでしょうか?

int main(int argc, int *argv[])
{
    Interface *itf;
    const char *name;

    {
        // loads the dll and gets functions
        PersistenInterface pi("PersistentInterface.dll");

        // returns a private implementation of the interface
        itf = pi.CreateInterface();
        name = itf->GetName();

        // CASE #1
        cout << name << endl; // suceeds

    } // dll is unloaded in ~PersistenInterface()

    // CASE #2
    //cout << name << endl; // crashes
    //cout << itf->GetName() << endl; // crashes

    {
        PersistenInterface pi("PersistentInterface.dll");

        // CASE #3
        cout << name << endl; // suceeds !?
        cout << itf->GetName() << endl; // suceeds !?
    }

    return 0;
}
4

2 に答える 2

2

DLL からスタック上のローカル オブジェクトを返していないことを願っています。関数が DLL から戻った後にローカル オブジェクトが破棄されるため、システムが確実にクラッシュします。DLL の概念とは関係ありません。含まれている関数が戻った後にローカル オブジェクトを参照しようとすると、同じ問題が発生します。

メモリが DLL 内のヒープに動的に割り当てられている場合、DLL が初期化されていない後もメモリは有効です。DLL 自体は何も所有していないため、メイン アプリケーションで引き続きメモリを使用できます。ヒープは DLL ではなくプロセスに属していることに注意してください。

ただし、一般的なルールは、そのメモリの所有者(そのメモリを作成する人、たとえばあなたの場合はDLL)が同じメモリを解放する責任があるということです。DLL でメモリを割り当て、反対側で割り当てを解除すると、不要な問題が発生する可能性があります。たとえば、2 つの側で CRT の異なるインスタンスが使用されている場合です。

于 2013-09-02T04:50:52.953 に答える