C++ Visual Studio 2013 Unwinding object

C++ Visual Studio 2013 Unwinding object

本文关键字:Unwinding object 2013 Studio Visual C++      更新时间:2023-10-16

嗯,我正试图构建这行代码,但我得到一个编译器错误。我试过在没有编译器的情况下构建,但这也不起作用。是关于__try__except的。有人告诉我把try块中的代码移到另一个函数中。但是我不明白这个:

错误12:不能在函数中使用__try对象解除

输入文件

void MSocketThread::Run()
{
    __try{
        //throw(pThread);
        while (true) {  // Waiting for SafeUDP Settting...
            DWORD dwVal = WaitForSingleObject(m_KillEvent.GetEvent(), 100);
            if (dwVal == WAIT_OBJECT_0) {
                return;
            }
            else if (dwVal == WAIT_TIMEOUT) {
                if (m_pSafeUDP)
                    break;
            }
        }
    WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
    WORD wEventIndex = 0;
    bool bSendable = false;
    WSANETWORKEVENTS NetEvent;
    WSAEVENT hFDEvent = WSACreateEvent();
    EventArray[wEventIndex++] = hFDEvent;
    EventArray[wEventIndex++] = m_ACKEvent.GetEvent();
    EventArray[wEventIndex++] = m_SendEvent.GetEvent();
    EventArray[wEventIndex++] = m_KillEvent.GetEvent();
    WSAEventSelect(m_pSafeUDP->GetLocalSocket(), hFDEvent, FD_READ | FD_WRITE);
    while (TRUE) {
        DWORD dwReturn = WSAWaitForMultipleEvents(wEventIndex, EventArray, FALSE, SAFEUDP_SAFE_MANAGE_TIME, FALSE);
        if (dwReturn == WSA_WAIT_TIMEOUT) {                 // Time
            m_pSafeUDP->LockNetLink();
            SafeSendManage();
            m_pSafeUDP->UnlockNetLink();
        }
        else if (dwReturn == WSA_WAIT_EVENT_0) {            // Socket Event
            WSAEnumNetworkEvents(m_pSafeUDP->GetLocalSocket(), hFDEvent, &NetEvent);
            if ((NetEvent.lNetworkEvents & FD_READ) == FD_READ) {
                //              OutputDebugString("SUDP> FD_READ n");
                m_pSafeUDP->LockNetLink();
                Recv();
                m_pSafeUDP->UnlockNetLink();
            }
            if ((NetEvent.lNetworkEvents & FD_WRITE) == FD_WRITE) {
                bSendable = true;
                //              OutputDebugString("SUDP> FD_WRITE n");
            }
        }
        else if (dwReturn == WSA_WAIT_EVENT_0 + 1) {        // ACK Send Event
            //          OutputDebugString("SUDP> ACK_EVENT n");
            FlushACK();
        }
        else if (dwReturn == WSA_WAIT_EVENT_0 + 2) {        // Packet Send Event
            //          OutputDebugString("SUDP> SEND_EVENT n");
            if (bSendable == true)
                FlushSend();
        }
        else if (dwReturn == WSA_WAIT_EVENT_0 + 3) {        // Kill the Thread
            break;  // Stop Thread
        }
    }
    WSACloseEvent(hFDEvent);
    // Clear Queues
    LockSend();
    {
        for (SendListItor itor = m_SendList.begin(); itor != m_SendList.end();) {
            delete (*itor);
            itor = m_SendList.erase(itor);
        }
    }
    {
        for (SendListItor itor = m_TempSendList.begin(); itor != m_TempSendList.end();) {
            delete (*itor);
            itor = m_TempSendList.erase(itor);
        }
    }
    UnlockSend();
    LockACK();
    {
        for (ACKSendListItor itor = m_ACKSendList.begin(); itor != m_ACKSendList.end();) {
            delete (*itor);
            itor = m_ACKSendList.erase(itor);
        }
    }
    {
        for (ACKSendListItor itor = m_TempACKSendList.begin(); itor != m_TempACKSendList.end();) {
            delete (*itor);
            itor = m_TempACKSendList.erase(itor);
        }
    }
    UnlockACK();
}
__except (this->CrashDump(GetExceptionInformation()))

基本上,SEH和c++展开并不完全兼容;它们要求编译器在机器码级别修改函数,而MS显然决定不同时支持对两者的修改,因此任何函数只能支持SEH unwind动作(__except或__finally)或c++ unwind动作(catch或带有析构函数的对象)。

我怀疑你的问题出在循环中的迭代器上;它们可能有析构函数。虽然迭代器通常很简单,不需要析构函数,但调试迭代器却不是这样,调试迭代器通常在构造时注册它们的存在,在析构时取消注册,以便检测无效的迭代器和其他无效的用法。

通常的解决方法是拆分函数。让你的run函数只包含以下内容:

void MSocketThread::Run()
{
    __try {
      RunNoSeh();
    } __except (this->CrashDump(GetExceptionInformation())) {
    }
}
void MSocketThread::RunNoSeh()
{
    // Code that was inside the __try goes here.
}
相关文章: