13

背景: DirectX 9.0 Managed Libraries を使用して、3D ポイントの配列を 2D 画面座標に変換しています。速度を上げるために、UnsafeNativeMethods を使用してすべての変換を行います。

問題: カスタムのライン クリッピング関数を使用すると、例外をスローせずにアプリケーションが停止します。キャッチできない System.ExecutionEngineException. クリッピング関数の最後の 2 行のために、発生に絞り込みました。

List<Vector3> verticesAfterClipping = new List<Vector3>;
public unsafe void ClipLine(Line lineToClip)
{
    this.verticesAfterClipping.Clear();

    // Clipping algorithm happens here... (this is psuedo-code of what it does)
    foreach(Vertex in lineToClip.Vertices)
    {
        bool thisIsClipped =   // Set to whether this vertex is clipped
        bool lastWasClipped =  // Set to whether last vertex was clipped

        if(thisIsClipped == false && lastWasClipped == true)
        {
            verticesAfterClipping.Add( /* intersection on clipping plane */ );
            verticesAfterClipping.Add( /* thisVertex */ );
        }
        else if (thisIsClipped == false && lastWasClipped == false)
        {
            verticesAfterClipping.Add( /* thisVertex */ );
        }
        else if (thisIsClipped == true && lastWasClipped == false)
        {
            verticesAfterClipping.Add(/* intersection on clipping plane */);
        }
    }

    // THIS IS WHERE BAD THINGS HAPPEN
    lineToClip.Vertices = new Vertex[verticesAfterClipping.Count];
    verticesAfterClipping.CopyTo(lineToClip.Vertices, 0);
}

verticesAfterClippingリストがlineToClip頂点にコピーされると、オブジェクトlineToClipは UnsafeNativeMethod に渡され、これらの頂点が 2D 頂点に変換されます。デバッグモードでステップスルーしたときに見ることができるすべてのものから、死ぬまで完全に正常に動作しています。

私は単に何が間違っているのか理解できません。どんな助けでも大歓迎です。

4

3 に答える 3

26

例外をスローする行では、実際には問題が発生していない可能性があります。これは、以前に起こったことの症状である可能性があります。

何かがひどく間違っていることをCLRが検出すると、System.ExecutionEngineException例外がスローされます。これは、問題が発生してからかなりの時間が経過した後に発生する可能性があります。これは、例外が通常、内部データ構造の破損の結果であるためです。CLRは、何かが意味のない状態になったことを検出します。続行するのは安全ではないため、キャッチできない例外がスローされます。

したがって、システムのまったく関係のない部分に何かを破壊するコードがあるかもしれませんが、これはこの特定のコードが実行されたときにのみ明らかになります。あなたが示したコードは問題ないかもしれません。(そうではないかもしれません...明らかな間違いは見当たりませんが、DX 9マネージドライブラリについてはよくわかりません。たとえば、このメソッドのどの機能に安全でないキーワードが必要かわかりません。 )。

残念ながら、これはネットを少し広くキャストし始める必要があることを意味します。安全でないコードまたはCOM相互運用機能のいずれかを使用するほとんどすべてのものが疑わしい可能性があります。悲しいことに、これは長くて退屈なプロセスになります。あなたがそれに近づくかもしれない一つの方法は、プログラムを徐々に単純化することを試みることです:問題を説明することができるコードの最小の部分は何ですか?(たとえば、そこに示したコードを、そのメソッドへの可能な限り単純な呼び出し以外は何も含まないアプリケーションに配置した場合でも、失敗しますか?)

于 2010-11-05T09:51:36.293 に答える