2012-11-10 29 views
1

我目前使用下面的功能打印我的調試字符串:醒目va_list的錯誤

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); } 
     } 
    } 

我只是覺得不能接受的是我的函數打印出我的調試字符串在本身的錯誤。有任何想法嗎?所有關於錯誤代碼/觀察的評論都是受歡迎的

+0

你有沒有嘗試過更大的outstring緩衝區? – didierc

+1

我沒有看到自定義調試功能在您的C#代碼中使用的位置。 – didierc

+0

我的c#代碼中沒有自定義調試功能。代碼例如:OutputDebugStringN(「[Script :: ParseTokens] Searched Bookmark:%s found \ n」,bookmark);如果書籤是通過引用傳入的變量,則會觸發內存錯誤。 – dk123

回答

1

按照C++標準在C++中傳遞帶有va_start的引用args是未定義的行爲。這意味着你無法預測編譯器會做什麼。即使這個編譯器有效,它可能無法在另一個編譯器上工作。它甚至可能不適用於相同編譯器的下一個版本。

也就是說,可能有平臺特定的構造,這將有助於您引發異常。例如。在Windows上,您應該可以使用_try/_except來捕捉異常。但要警告的是,這是未定義的行爲 - 即使它在此版本的編譯器中工作,在下一個版本中,va_start可能會決定做一些完全不同的事情,這可能會導致其他錯誤&不是可以在__try/__except中捕獲的崩潰

+0

有沒有辦法,然後檢查可能檢查是否傳入的參數(s)通過價值還是參考? – dk123

+0

@ Evergreen123號這就是爲什麼可變參數被認爲是邪惡的原因 - 因爲你失去了類型檢測 – user93353

+0

感謝您的回覆。然後是否有可能的替代方法,我可以去執行一個可變的outputdebugstring版本?我仍然對繼續目前的實施感到不安 – dk123