1

現在、以下の関数を使用してデバッグ文字列を出力しています。

void Script::OutputDebugStringN(const char *format, ...)
{
    char outstring[256];
    memset(outstring, 0, sizeof(outstring));

    try
    {
        va_list args = {0};
        va_start(args, format); //args = (va_list) (&format+1);

        vsprintf(outstring, format, args);

        va_end(args);

        OutputDebugString(outstring);
    }
    catch (...) //most likely reference val arg error (va_list doesn't support ref args)
    {
        OutputDebugString("[OutputDebugStringN] Something went wrong\n");
    }
}

参照値の引数を送信するたびに、「タイプ 'System.AccessViolationException' の未処理の例外が Editor.exe で発生しました」というエラー メッセージが表示されます。これは完全に理解できますが、エラーがプログラム全体をシャットダウンするのを防ぐために、これを try catch ステートメントにカプセル化する方法を考えています。(上記は動作しません)

現在、C# エディターから自作の c++ dll (上記の関数を使用) を呼び出しています。

C# コードは次のとおりです。

private void ComponentDispatcher_ThreadIdle(object sender, EventArgs e)
    {
        //render display window (if something is not blocking it)
        if (renderViewHost.Update)
        {
            try { NativeMethods.UpdateRenderWindow(); }
            catch (Exception exc)
            { Debug.WriteLine("[ThreadIdle::UpdateRenderWindow] Exception caught: {0}" + exc); }
        }
    }

デバッグ文字列を出力する関数自体にエラーがあることは受け入れられません。何か案は?悪いコード/観察に関するすべてのコメントを歓迎します。

4

1 に答える 1

1

va_start を使用して参照引数を渡すことは、C++ 標準に従って、C++ では未定義の動作です。つまり、コンパイラが何をするかを予測することはできません。このコンパイラで何かが機能しても、別のコンパイラでは機能しない場合があります。同じコンパイラの次のバージョンでも動作しない可能性があります。

とはいえ、例外を引き起こすのに役立つプラットフォーム固有の構造が存在する可能性があります。たとえば。Windows では、 _try / _exceptを使用して例外をキャッチできるはずです。ただし、これは未定義の動作であることに注意してください。このバージョンのコンパイラで機能する場合でも、次のバージョンでは、va_start がまったく異なることを決定する可能性があり、他のエラーが発生する可能性があります。__try/__except

于 2012-11-10T01:42:11.250 に答える