如何在C ++中手动运行消息泵

时间:2011-06-14 08:48:08

标签: c++ windows visual-c++ mfc

原始问题

我们的应用程序使用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 + Unmanaged DLL导入的两个函数。

我不完全确定Visual C ++项目的,这是为了能够对泵做任何事情,说实话。

希望这些额外数据有用。

3 个答案:

答案 0 :(得分:3)

最简单的消息循环如下所示:

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

但是我不确定这真的能回答你的问题 - 你不能只是在你喜欢的任何地方运行一个消息循环。所以我们需要更多细节。

答案 1 :(得分:2)

我翻译的C ++代码如下(未选中:) PS:调用DLLStart,DLLStop在同一个线程中会更可靠。

全局变量包含threadID
DWORD threadID = 0;

在OnStart中等效:
CreateThread(0, 0, PumpThread, 0, 0, 0);

在OnStop中等效:
PostThreadMessage(threadID, WM_QUIT, 0, 0);

线程例程:

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();
}

答案 2 :(得分:1)

您必须创建用户界面线程。工作线程没有消息泵

查看CWinThread