将STL(c++11)与WinAPI相结合

Combining STL(c++11) with WinAPI

本文关键字:WinAPI 相结合 c++11 STL      更新时间:2023-10-16

我试图使用CreateThread启动一个新线程,并将shared_pointer的指针作为参数传递。如果我要使用好的旧ATL,它会调用Ccomptr的运算符((并增加引用计数,最终检索指针。

我正试图使用STL的shared_ptr来做同样的事情,但我遇到了一个错误,std::shared_ptr到LPVOID之间的转换不存在。

        std::shared_ptr<X> m_pSettings = std::make_shared(new ....);
        if (nullptr == (m_hBackgroundThread = ::CreateThread(
            nullptr,                // default security attributes
            0,                      // use default stack size  
            ThreadProc,             // thread function name
            m_pSettings,            // argument to thread function 
            0,                      // use default creation flags 
            0)))
        {
            LOG_ERROR(L"Failed to create thread");
            return false;
        }

正确的答案,正如您已经被告知的,是使用std::thread:

// Hey, look: No magic nullptrs and zeros nobody ever changes to non-defaults anyway!
std::thread t(ThreadProc, m_pSettings);
// Don't forget to
t.detach();
// if you let the std::thread object destruct without first joining it and making sure
// the thread finishes executing

std::thread不仅解决了你的问题,它还有很多其他好处,比如允许你无需大惊小怪地传递多个参数,它复制/移动/对你传递的参数做正确的事情,等等。它不需要你使用任何所谓的聪明但实际上不是黑客。如果使用std::async而不是std::thread,您甚至可以在调用方线程中获得导致线程函数展开的异常(如果有的话(。

如果您非常小心的话,将shared_ptr的地址传递给CreateThread,然后在ThreadProc中取消对其的引用的方法可能会奏效——至少您必须确保在ThreadProc处理完它之前,调用者的shared_ptr不会消失——但这只是要求发生坏事。

当然,如果你别无选择,那就是你要做的,但考虑到std::thread和朋友们做任何其他事情都是错误的,都是浪费时间。


此外,您与ATL的比较似乎是基于误解。ATL的智能指针非常聪明,即使在给你原始指针的时候也能以某种神奇的方式保持引用计数(尽管我不知道CComPtr::operator()(,而C++标准库的智能指针是蹩脚的,不能做到这一点。区别在于管理保留自己的引用计数和管理自己的生存期的特殊对象(假设您在使用它们时声明((即调用AddRef(和任意资源。

COM的智能指针(无论是CComPtr_com_ptr_t,还是任何你在网上完善的半生不熟的lame类(基本上是COM对象固有的管理其生存期的能力的包装。

您可以将AddRedRelease等(显然带有相关的语义(添加到类X中,并将其封装在COM智能指针中。。。

您可以通过如下指针传递shared_ptr对象:&m_pSettings

然后在您的ThreadProc:中取消引用它

  std::shared_ptr<X> pSettings = *static_cast<std::shared_ptr<X>*>(lpParam);

可能您需要先复制shared_ptr,然后再将指向它的指针传递到CreateTrhead中,这样在ThreadProc运行时它就会在作用域中。