- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想升级我的 MFC 生产代码以使用 std::shared_ptr
调用其他窗口或线程时的智能指针。此类电话是 SendMessage
, PostMessage
和 PostThreadMessage
哪个通过 wparam
和 lparam
和分别是 unsigned int
和 long
.目前,我创建一个类对象,新建一个对象,调用传递一个指向该对象的指针,在接收端使用该对象,然后将其删除。
自 shared_ptr
在我的其余代码中效果很好,我想至少探索一下为什么我不能对 Windows 调用做同样的事情的原因。
当前通话:
auto myParams = new MyParams(value1, value2, value3);
PostThreadMessage(MSG_ID, 0, reinterpret_cast< LPARAM >( myParams );
ReceivingMethod::OnMsgId( WPARAM wParam, LPARAM lParam)
{
auto myParams = reinterpret_cast< MyParams * >( lParam );
... // use object
delete myParams;
}
std::shared_ptr< MyParams > myParams( new MyParams( value1, value2, value3 ) );
PostThreadMessage( MSG_ID, 0, ???myParams??? );
ReceivingMethod::OnMsgId( WPARAM wParam, LPARAM lParam )
{
auto myParams = ???lParam???;
... // use object
}
struct Logger
{
Logger()
{
errorLogger = ( ErrorLogger * )AfxBeginThread( RUNTIME_CLASS( ErrorLogger ), THREAD_PRIORITY_BELOW_NORMAL );
}
~Logger()
{
// gets properly dtor'ed upon app exit
}
void MakeLogMsg( ... );
ErrorLogger * errorLogger;
std::unique_ptr< LogParams > logParams;
};
Logger logger;
std::recursive_mutex logParamsRecursiveMu; // because of multiple requests to lock from same thread
struct ErrorLogger : public CWinThread
{
ErrorLogger()
{
}
~ErrorLogger()
{
// gets properly dtor'ed before logger upon app exit
}
afx_msg void OnLog( WPARAM wParam, LPARAM lParam );
};
void Logger::MakeLogMsg( ... )
{
// construct msg from logparams
// make msg smart object using unique ptr and send to errorlogger thread queue
logParams = std::make_unique< LogParams >();
// set logparams
// with the addition of the mutex guard, the leaks are gone
logParamsRecursiveMu.lock();
logger.errorLogger->PostThreadMessage( ONLOG_MSG, 0, reinterpret_cast< LPARAM >( logParams.get() ) );
logParams.release(); // no longer owns object
logParamsRecursiveMu.unlock();
}
void ErrorLogger::OnLog( WPARAM wParam, LPARAM lParam )
{
std::unique_ptr< LogParams > logParams( reinterpret_cast< LogParams * >( lParam ) );
}
@Remy Lebeau
's answer显示如何
std::unique_ptr
可以用来代替
std::shared_ptr
,我在下面的评论中表示“......没有额外的对象要实现。没有明显的缺点。”。嗯,这并不完全正确。
MyParams
必须为每种不同类型的消息创建对象。有些应用程序可能只有几种类型,但有些应用程序可能有 100 个或更多。每次我想在另一边执行一个函数时,我都必须制作一个新的结构,它有一个构造函数,它接受目标调用的所有参数。如果有很多,则实现起来非常繁琐且难以维护。
std::forward_as_tuple
其中“构造一个对 args 中参数的引用元组,适合作为参数转发给函数。”
MyParams
解决了这个问题,但对于任何想要避免添加大量结构的人来说,他可能想考虑使用元组等。
new
的已发布代码描述的上下文回答了该问题。编辑
MyParams
(有关更多解释,请参阅编辑 2:)。后来在答案 5 (rtischer8277) 中,我根据问题的原始措辞自己回答了这个问题,该问题询问是否
std::shared_ptr
可以使用
PostThreadMessage
跨线程使用.作为一个合理的结果,我已将正确答案重新分配给@RemyLebeau,这是第一个正确答案。
future
为了控制所有权和同步,它没有展示如何使用任意数量的参数创建消息对象,这些参数可以安全地用于 PostThreadMessage 调用的任一侧。 StackOverflow's Answer to issue
passing a parameter pack over a legacy function signature using forward_as_tuple 中解决了该功能.
最佳答案
由于消息参数必须超过调用范围,因此使用 shared_ptr
没有多大意义。在本例中,作为源 shared_ptr
最有可能在处理消息之前超出范围。我建议使用 unique_ptr
相反,您可以 release()
指针在飞行中,然后在处理消息后获得它的新所有权:
SendingMethod::SendMsgId( ... )
{
...
std::unique_ptr<MyParams> myParams( new MyParams(value1, value2, value3) );
if (PostThreadMessage(MSG_ID, 0, reinterpret_cast<LPARAM>(myParams.get()))
myParams.release();
...
}
ReceivingMethod::OnMsgId( WPARAM wParam, LPARAM lParam)
{
std::unique_ptr<MyParams> myParams( reinterpret_cast<MyParams*>(lParam) );
... // use object
}
关于c++11 - 如何使用 PostThreadMessage 使用 shared_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25667226/
我有一个事件处理线程类,它允许我从其他线程引发事件而不中断它们的操作。当调用析构函数时,我向线程发送一条退出消息,但它的消息循环似乎没有收到这条消息。 #include using namespac
我有三个问题。 1. 将 PostThreadMessage 用于 CWinThread 是否安全? 2. 使用 SendMessage 安全吗(在两个应用程序之间)? 消息可以消失吗?SendMes
我不太确定这是否是正确的方法(我是爱好者)。我想将消息发布到循环 GetMessage() 并根据消息执行某些操作的工作线程。我知道我必须将 postthreadmessage() 与该工作线程的句柄
对于 WPF 应用程序,Application.Run 内部是否存在经典的消息循环(在 Windows 的 GetMessage/DispatchMessage 意义上)?是否可以使用 PostThr
今天,我看到了这样一段代码: void Foo() { MyMsgStruct myMsg; /* omission for simplicity */ /* send to
我想向作为另一个进程(特别是作为 Windows 服务)运行的线程发送消息。我已阅读 PostThreadMessage 的文档但有些事情我不清楚。 如何获取服务线程的句柄? The system o
我的 C++ 应用程序中有一个(静态)线程,它经常执行某些操作。为了在线程和我的应用程序之间交换信息,我使用方法 PostThreadMessage 和 PeekMessage。 由于某些原因,我不能
我想使用 Windows 的消息队列功能将结构发送到另一个线程。但是我发现postthreadmessage函数只提供了两个整型参数,lparam和wparam供我传递参数。所以我决定把struct的
我正在尝试使用 WM_COPYDATA 将数据从一个应用程序发送到另一个应用程序。这两个应用程序都是控制台并且没有窗口。我可以很好地发送用户消息。当我尝试发送 WM_COPYDATA 并设置数据结构或
我想升级我的 MFC 生产代码以使用 std::shared_ptr调用其他窗口或线程时的智能指针。此类电话是 SendMessage , PostMessage和 PostThreadMessage
在 PostThreadMessage 中,我的线程 ID 是正确的,但我收到错误 1444(“无效的线程标识符。”)。 有人知道怎么解决吗? 最佳答案 操作系统是线程 ID 是否有效的权威,因此如果
我正在将应用程序移植到 Mac OS X。 我也需要在 Mac OS X 上执行以下任务。线程A需要向另一个线程B的消息队列投递消息。这些消息也涉及一些自定义消息。在像 EXIT_LOOP 这样的特定
我正在处理一些遗留代码,这些代码使用 MFC 的 UI 线程来实现管理器线程-工作线程机制。代码过去在 MFC GUI 应用程序下运行,但现在它在一个单独的 dll 中,并且可以从 GUI 应用程序和
好的,我正在使用 CreateRemoteThread/LoadLibrary 将一些代码注入(inject)到另一个进程中“把戏”。 我最终得到了一个线程 ID,以及一个带有我选择的 DLL 的进程
我有一个使用 Boost 1.47.0 的 Visual Studio 2008 C++ 项目,我需要在其中获取 boost::thread 的 native Windows ID 以传递给 Post
我正在尝试启动 iexplore.exe 让它运行 5 秒钟,然后再次将其关闭。 iexplore 打开很好,但是当我调用 PostThreadMessage 时它没有关闭。谁能看到我做错了什么?这是
我有一个单服务器多客户端 udp 应用程序。有一个线程(thread#1)和一个套接字(socket#1)连续接收来自 client#1 的数据。这个接收线程的任务是在它的套接字上不断地接收数据。 我
我是一名优秀的程序员,十分优秀!