如何在 C++ 中手动运行消息泵
原始问题
我们的应用程序使用 CSocket,它需要运行消息泵才能工作。目前,更改为另一个套接字实现是不切实际的,尽管这是我们希望在某个时刻结束的地方。
该应用程序采用 Visual C++(非托管)。
目前,我们使用 C#.NET 服务启动器来启动 C++ DLL,该服务启动器通过 Application.Run 启动线程来启动消息泵,然后使用 DllImport 来启动 DLL 中的 start 方法。
这会带来很多问题,其中最紧迫的是,如果 DLL 由于任何原因崩溃,我们将无法获得转储文件!
因此,我们正在切换到 C++ 服务启动器,虽然我们对它的服务方面很满意,但我们对如何让消息泵运行有点困惑。
我浏览了谷歌和这里的一些问题,但我的部分问题是缺乏基本的 C++ 知识,所以如果这是一个愚蠢的问题,我深表歉意,如果有人能指出我正确的方向,我将不胜感激。
预先非常感谢 Matt Peddlesden
更多信息
我们试图替换的当前 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)
{
}
}
本质上,我们只是尝试用 C++ 等效项替换上面的 C# .NET Windows 服务,以便我们的代码运行完全在非托管世界中,而不是不必要地将其与 5 行托管代码混淆。
DLLStart() 和 DLLStop() 是从 C+ 非托管 DLL 导入的两个函数,它们实际上启动和停止系统。
老实说,我并不完全确定需要什么样的 Visual C++ 项目才能使用泵执行任何操作。
希望这些附加数据有用。
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.
The application is in Visual C++ (NOT managed).
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.
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!
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.
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.
Many thanks in advance
Matt Peddlesden
MORE INFORMATION
The current C# service that we are trying to replace does essentially this:
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.
DLLStart() and DLLStop() are two functions that are imported from our C+ Unmanaged DLL that actually start and stop the system.
I'm not entirely sure what kind of Visual C++ project this would need to be in order to be able to do anything with the pump either to be honest.
Hope this additional data is useful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最简单的消息循环看起来像这样:
但我不确定这是否真正回答了您的问题 - 您不能在您喜欢的任何地方运行消息循环。所以我们需要更多细节。
A message loop at its simplest looks like this:
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.
我翻译的 C++ 代码如下(未检查:)
PS:在同一个线程中调用DLLStart、DLLStop会更可靠。
全局变量保存threadID
DWORD threadID = 0;
在 OnStart 中等效项:
CreateThread(0, 0, PumpThread, 0, 0, 0);
在 OnStop 中等效:
PostThreadMessage(threadID, WM_QUIT, 0, 0);
线程例程:
My translated C++ code is below (not checked :)
PS: Calling DLLStart, DLLStop in the same thread will be more reliable.
A global variable holds threadID
DWORD threadID = 0;
In OnStart equivalent:
CreateThread(0, 0, PumpThread, 0, 0, 0);
In OnStop equivalent:
PostThreadMessage(threadID, WM_QUIT, 0, 0);
Thread routine:
您必须创建一个用户界面线程。工作线程没有消息泵
请查看 CWinThread
You'll have to create a user-interface thread. Worker threads have no message pump
Have a look at CWinThread