0

私はこの機能を持っています、

vector<QDC::AdapterUserInfo> QDC::QueryInterface::RetrieveAdapterList()
{
    vector<QDC::AdapterUserInfo> retVal;
    InnerQueryInterface::IISTATE::Transition trans = _IQI->AdapterList(retVal);
    if (trans._OldState == trans._NewState)
    {
        if ( trans._NewState != InnerQueryInterface::IISTATE(trans._OldState).SuccessfulTransition(trans._Transition) )
        {
            throw Exceptions::FunctionFailed();
        }
    }
    return retVal;
}

QDC名前空間です。QueryInterfaceを使用してエクスポートされるクラス__declspec(dllexport)です。( lib を含む DLL が生成されます ) 他のプロジェクトでは、この関数を次のように使用します。

vector<QDC::AdapterUserInfo> aui = Qui.RetrieveAdapterList();

ただし、リリース ビルドでは、ベクターは常にサイズ 0 で返されます。ただし、サイズ 1 (実際の要素数) で返されます。リリース モードでデバッグしたところretVal、関数内がRetrieveAdapterList実際のデータで満たされ、関数の最後の行であるline で、ベクトルが空になるreturn retVal;ことが示されていることがわかりました。そのため、最後に返される値は空のベクターです。retValcleared

なぜこうなった?なにが問題ですか?なぜデバッグモードで動作するのですか?

- 編集 -

auiスコープの最後まで実行を続けた後、ベクトルのデストラクタが失敗したようです。

-- 発信者からのコード --

void DXE::Screen::Initialize( const HWND in_Window, const bool in_Windowed )
{
    QDC::UsableParameters UP;
    QDC::QueryInterface Qui;
    vector<QDC::AdapterUserInfo> aui = Qui.RetrieveAdapterList();
    if( aui.size() <= 0 )
    {
        throw Exceptions::UnknownException();
    }
    Qui.SelectAdapter(0);
    Qui.SelectDisplayMode(in_Windowed);
    UP = Qui.RetrieveParameters();

    _AdapterOrdinal = UP._AdapterOrdinal;

    _D3DPresentParams.BackBufferWidth = UP._Width;
_D3DPresentParams.BackBufferHeight = UP._Height;
_D3DPresentParams.BackBufferFormat = UP._BackBufferFormat;
    //..... fills the _D3DPresentParams..
}

-- 編集: 結論 --

何度も試行した後、ヒープ クラッシュが発生した可能性があるというエラー メッセージが表示され、Peter Ruderman が提案した原因が突き止められました。それで、動的ライブラリから静的ライブラリに変更して、その場合にそのようなヒープが発生しないようにしました(少なくともそれが私が考えていたことです)。その後、プログラムは問題なく正常に動作するように見えました。したがって、ピーターの理論は正しかったという結論になるはずです。助けてくれてありがとう。

4

2 に答える 2

1

これはバグの原因ではありません。VS2010 が使用する C++11 の初期バージョンでは、ベクトルは移動構築可能です。return ステートメントでは、ローカル変数 retval が右辺値になるため、コンパイラはその内容を呼び出しサイトの "aui" 変数に移動します。(事実上、aui と retval の内容を交換するだけです。) デバッグ ビルドもトレースすると、この動作が見られるはずです。

于 2013-01-18T20:41:59.147 に答える
1

別の理論:

"QDC は名前空間です。QueryInterface は __declspec(dllexport) を使用してエクスポートされるクラスです。(lib を含む DLL が生成されます)"

私がこれを正しく理解していれば、関数 Screen::Initialize は実行可能モジュールに存在しますが、関数 QueryInterface::RetrieveAdapters list は DLL に存在すると言っています。この場合、DLL はメモリを割り当ててから呼び出しサイトに移動します。aui が範囲外になると、exe はメモリを削除します。DLL と exe が異なるヒープを使用している場合、重大なエラー (ヒープの破損) が発生する可能性があります。

于 2013-01-18T21:22:19.610 に答える