为什么从win32计时器回调中抛出我的析构函数? [英] Why aren't my destructors called when throwing from a win32 timer callback?

查看:114
本文介绍了为什么从win32计时器回调中抛出我的析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚问过这个问题。简而言之,当你从win32计时器回调中抛出时,异常似乎不会去任何地方。它似乎被Windows秘密处理。

I just asked this question. In short, when you throw from a win32 timer callback, the exception doesn't appear to go anywhere. It seems to be surreptitiously handled by Windows somewhere.

好的,这是一个问题。另一方面的问题是,当抛出异常时,析构函数似乎没有被调用。在下面的代码中,对于CFoo的 std :: vector ,输出的唯一时间是当GetFooVect中的临时值被破坏时,并且rValue被复制到fooVect。 fooVect的内容没有被破坏。

OK well thats a problem. The OTHER side of the problem is that destructors don't seem to be getting called when this exception IS thrown. In the following code, for the std::vector of CFoo, the only time "~CFoo" is output is when the temporaries in GetFooVect are destructed and when the rValue is copied to fooVect. The contents of fooVect are NOT destructed.

这是我最糟糕的噩梦。我非常喜欢RAII。我非常重视我的析构函数,以适当地清理。

This is my worst nightmare. I use RAII pretty heavily. I lean pretty heavily on my destructors to cleanup appropriately.

class CFoo
{
public:
    ~CFoo() {printf(__FUNCTION__ "\n");}
};

std::vector< CFoo > GetFooVect()
{
    std::vector< CFoo > rValue;
    rValue.push_back(CFoo());
    rValue.push_back(CFoo());
    rValue.push_back(CFoo());
    return rValue;
}

VOID CALLBACK Timer(HWND hwnd,
    UINT uMsg,
    UINT_PTR idEvent,
    DWORD dwTime)
{
    // My destructors aren't called?
    std::vector< CFoo> fooVect = GetFooVect();

    // I'm destroyed
    CFoo aFoo;

    throw FooExcept();
    printf("Also Here\n");
}

我尝试通过简单地抛出/捕捉C ++异常来重新创建它(即删除win32计时器回调变量)和CFoo的destructs的向量就好了。由于某些原因,析构函数在这里不被称为向量中的东西。是什么赋予了?有没有逻辑的解释,或者是奇怪的,还是两者?

I've tried recreating this by simply throwing/catching C++ exceptions (ie removing the win32 timer callback variable) and the vector of CFoo's destructs just fine. For some reason, destructors are NOT being called here for things in vectors. What gives? Is there a logical explanation for this, or is it just weird, or both?

推荐答案

你永远不应该允许异常通过C API边界传播(如SetTimer回调)。 C代码(和Windows API函数)不了解C ++语言异常。您不能依赖此类代码来传播异常。

You should never, ever allow am exception to propagate across a C API boundary (like the SetTimer callback). C code (and the Windows API functions) know nothing about C++ language exceptions. You cannot rely on such code to propagate your exceptions.

您的回调应该在返回并适当处理异常之前捕获所有C ++语言异常。如果您需要以某种方式将异常与您的应用程序的其余部分进行通信,则需要自行执行。

Your callback should catch all C++ language exceptions before returning and handle the exceptions appropriately. If you need to somehow communicate the exceptions to the rest of your application, you need to do so yourself.

(这里有人可能可以详细解释这种情况发生了什么,但简短的答案是你不能依靠C代码做在C ++语言异常的情况下正确的事情,因为它不知道C ++语言异常是什么。)

(Someone else here may be able to explain in detail what is happening in this case, but the short answer is that you can't rely on C code to do the right thing in the presence of a C++ language exception, because it has no idea what a C++ language exception is.)

这篇关于为什么从win32计时器回调中抛出我的析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆