windows 如何在 C++ 中手动运行消息泵
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6341148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to manually run message pump in C++
提问by Matt Peddlesden
ORIGINAL QUESTION
原问题
Our application uses CSocket which requires the message pump to be running in order for it to work. Currently it's not practical to change to another socket implementation, though that is where we'd like to end up at some point.
我们的应用程序使用 CSocket,它需要消息泵运行才能工作。目前,改变到另一个套接字实现是不切实际的,尽管我们希望在某个时候结束。
The application is in Visual C++ (NOT managed).
该应用程序采用 Visual C++(非托管)。
We currently launch the C++ DLL by using a C#.NET service launcher that kicks off a thread with an Application.Run to get the message pump going, and then uses DllImport to fire off the start method in our DLL.
我们目前通过使用 C#.NET 服务启动器启动 C++ DLL,该启动器使用 Application.Run 启动一个线程以启动消息泵,然后使用 DllImport 启动我们的 DLL 中的 start 方法。
There are numerous problems with this, the most pressing of which is that if the DLL crashes for any reason we don't get a dump file!
这有很多问题,其中最紧迫的是,如果 DLL 因任何原因崩溃,我们将无法获得转储文件!
As a result of this, we're switching to a C++ service launcher, and while we're fine with the service aspect of it we're a bit stumped on how to get the message pump going.
因此,我们正在切换到 C++ 服务启动器,虽然我们对它的服务方面很好,但我们对如何启动消息泵有点困惑。
I had a look around google and some questions on here but part of my problem is a lack of basic C++ knowledge so apologies if this is a dupe question, if someone can point me in the right direction that would be much appreciated.
我浏览了 google 并在这里找到了一些问题,但我的问题的一部分是缺乏基本的 C++ 知识,所以如果这是一个欺骗性的问题,我很抱歉,如果有人能指出我正确的方向,我将不胜感激。
Many thanks in advance Matt Peddlesden
提前非常感谢马特 Peddlesden
MORE INFORMATION
更多信息
The current C# service that we are trying to replace does essentially this:
我们试图替换的当前 C# 服务本质上是这样的:
public void PumpThread()
{
DLLStart();
Application.Run();
}
protected override void OnStart(string[] args)
{
try
{
Thread pumpThread = new Thread(new ThreadStart(PumpThread));
pumpThread.IsBackground = true;
pumpThread.Start();
}
catch (DllNotFoundException dnfe)
{
}
catch (Exception e)
{
}
}
protected override void OnStop()
{
try
{
DLLStop();
}
catch (DllNotFoundException dnfe)
{
}
catch (Exception e)
{
}
}
Essentially we're simply trying to replace the above C# .NET Windows Service with a C++ equivalent so that our code is running entirely in the unmanaged world rather than unnecessarily confusing this with 5 lines of managed code.
本质上,我们只是试图用 C++ 等效项替换上面的 C# .NET Windows 服务,以便我们的代码完全在非托管世界中运行,而不是不必要地将其与 5 行托管代码混淆。
DLLStart() and DLLStop() are two functions that are imported from our C+ Unmanaged DLL that actually start and stop the system.
DLLStart() 和 DLLStop() 是从我们的 C+ 非托管 DLL 中导入的两个函数,它们实际启动和停止系统。
I'm not entirely sure what kindof Visual C++ project this would need to be in order to be able to do anything with the pump either to be honest.
老实说,我不完全确定这需要什么样的 Visual C++ 项目才能使用泵做任何事情。
Hope this additional data is useful.
希望这些额外的数据是有用的。
采纳答案by 9dan
My translated C++ code is below (not checked :)
PS: Calling DLLStart, DLLStop in the same thread will be more reliable.
我翻译的 C++ 代码如下(未检查 :)
PS:在同一线程中调用 DLLStart、DLLStop 会更可靠。
A global variable holds threadIDDWORD threadID = 0;
一个全局变量保存 threadIDDWORD threadID = 0;
In OnStart equivalent:CreateThread(0, 0, PumpThread, 0, 0, 0);
在 OnStart 等效项中:CreateThread(0, 0, PumpThread, 0, 0, 0);
In OnStop equivalent:PostThreadMessage(threadID, WM_QUIT, 0, 0);
在 OnStop 等效项中:PostThreadMessage(threadID, WM_QUIT, 0, 0);
Thread routine:
线程例程:
DWORD WINAPI PumpThread(void* param)
{
threadID = GetCurrentThreadId();
DLLStart();
// create thread message queue
PeekMessage(&msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DLLStop();
}
回答by Matt Peddlesden
A message loop at its simplest looks like this:
最简单的消息循环如下所示:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
but I'm not sure that really answers your question - you can't just run a message loop anywhere you take a fancy to. So we need more details.
但我不确定这是否真的能回答你的问题——你不能在你喜欢的任何地方运行消息循环。所以我们需要更多的细节。
回答by Chris Bednarski
You'll have to create a user-interface thread. Worker threads have no message pump
您必须创建一个用户界面线程。工作线程没有消息泵
Have a look at CWinThread