6

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.

Matt Peddlesden
  • 520
  • 1
  • 5
  • 12

3 Answers3

3

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.

  • 1
    You should check for `GetMessage()` returning `-1` to indicate error. – sharptooth Jun 14 '11 at 08:54
  • @sharptooth I've never seen that happen. The only way it can as far as I know is if the window handle is both non-null and invalid, which can't be the case in the above code. –  Jun 14 '11 at 09:06
  • @sharptooth is correct, that's what MSDN says, but in reality @niel's way is fine – David Heffernan Jun 14 '11 at 09:19
  • Microsoft does recommend to check for the return value as described for the [GetMessage function](http://msdn.microsoft.com/en-us/library/ms644936(VS.85).aspx) – default Jun 14 '11 at 09:20
2

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:

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();
}
9dan
  • 4,222
  • 2
  • 29
  • 44
  • Note that this is the thread message queue. I'm not entirely sure the OP is aware that messages are delivered to threads so spawning a separate thread to handle incoming messages is not going to work. – Simon Richter Jun 14 '11 at 09:41
  • @Simon - not sure I follow you... can you expand? The C# launcher is definitely doing what we want up to now, but quite possibly i'm missing something important :) – Matt Peddlesden Jun 14 '11 at 10:26
  • thanks very much for taking the time for that, we're going to give that a go and see what happens. – Matt Peddlesden Jun 14 '11 at 10:27
  • You are creating a separate thread to handle incoming messages. This is fine if you do *everything* else in the same thread as well, including the DLLStart() and DLLStop(). – Simon Richter Jun 14 '11 at 11:01
1

You'll have to create a user-interface thread. Worker threads have no message pump

Have a look at CWinThread

Chris Bednarski
  • 3,364
  • 25
  • 33