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

每次发送参考值参数时,我都会收到“Editor.exe 中发生‘System.AccessViolationException’类型的未处理异常”错误消息;这是完全可以理解的,但我想知道如何将它封装在一个可能的 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

根据 C++ 标准,使用 va_start 传递引用参数在 C++ 中是未定义的行为。这意味着您无法预测编译器会做什么。即使某些东西在这个编译器中有效,它也可能不适用于另一个编译器。它甚至可能不适用于同一编译器的下一个版本。

也就是说,可能有特定于平台的构造可以帮助您导致异常。例如。在 Windows 上,您应该能够使用_try / _except来捕获异常。但是请注意,这是未定义的行为 - 即使它在此版本的编译器中工作,在下一个版本中,va_start 可能会决定做一些完全不同的事情,这可能会导致其他错误,而不是可能被捕获的崩溃__try/__except

于 2012-11-10T01:42:11.250 回答