2010-11-05 107 views
7

背景: 我正在使用DirectX 9.0託管庫將3d點的數組轉換爲2D屏幕座標。對於速度,我使用UnsafeNativeMethods進行所有轉換。爲什麼此代碼拋出System.ExecutionEngineException

問題: 如果使用我的自定義線裁剪功能,我的應用程序死了,沒有拋出任何異常,我花了一段時間才能弄清楚,它拋出一個抓不到System.ExecutionEngineException。由於剪輯功能的最後兩行,我縮小了範圍。

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中的頂點。當我以調試模式瀏覽它時,我能看到的所有東西都能正常工作,直到它死亡。

我根本無法弄清楚什麼是錯的。任何幫助將非常感激。

回答

12

該問題實際上可能不會在引發異常的行中發生。這可能只是早些時候發生的事情的一個症狀。

當CLR 檢測到某些事情已經發生了可怕的錯誤時,將引發System.ExecutionEngineException異常。問題發生後,這可能會發生相當長的時間。這是因爲異常通常是內部數據結構被破壞的結果 - CLR發現某些事情進入了一種毫無意義的狀態。它會拋出一個不可捕捉的異常,因爲它不安全。

因此,您可能會在某些完全不相關的系統中破壞某些東西的代碼,但只有在運行這段代碼時纔會變得明顯。你顯示的代碼可能會很好。 (它也可能不是......我沒有看到任何明顯的錯誤,但是我不知道DX 9託管庫的好處,例如,我看不到這個方法的哪個特徵需要不安全的關鍵字。 )

不幸的是,這意味着你需要開始投網更廣泛。幾乎任何使用不安全代碼的東西,或COM互操作都有可能被懷疑。可悲的是,這將是一個漫長而乏味的過程。你可能會採取的一種方法是逐漸簡化程序:能夠說明問題的最小代碼是什麼? (例如,如果你把你在那裏顯示的代碼放到一個應用程序中,除了對該方法的最簡單的調用,它是否仍然失敗?)

+0

當你說在這兩行中不發生異常時,你是對的,但它確實發生在這兩行的結果中。 我替換了這些行,並使用另一個臨時緩衝區來複制剪輯的頂點,現在一切正常。我認爲當這行被傳遞給不安全的本地directx方法時,會發生某種內存訪問衝突。 – tbridge 2010-11-08 00:10:37

+3

不要認爲沒有ExecutionEngineException意味着問題已消失。它可能僅僅是CLR不再檢測到它。通過替換這些行,您現在可能處於數據被破壞的情況,但您不再有異常。 (CLR沒有也不能保證在任何時候拋出ExecutionEngineException這樣的錯誤,只有當它發生時纔會拋出它。)所以我會擔心的 - 我一定會試圖到達底部*如何發生這次事故,就像現在一樣,沒有理由確信你已經修復了它。 – 2010-11-08 14:29:28

1

我對於不同的庫有同樣的問題。在我的情況下,所有人都開始很久以前,因爲我必須在64位環境中運行32位.net應用程序。那麼這會給我帶來很多麻煩,體系結構之間的兼容性問題,或者.NET框架的CLR問題也可能是您的問題。

PS:現在我知道什麼我的麻煩是,但不知道其中是它。

相關問題