Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encapsulate Windows message loop into a DLL

Tags:

c++

dll

winapi

I would like to have a DLL with window creation and management code in a way that the developer could just add a named main.h header and load the DLL to be able to instance a window.

#include "dllheader.h" 

void user_main();

main = user_main; // attach user main to the dll callback

int user_main() {
    Window *w = new Window();
}

on the DLL side the code should look like

void (*main)() = NULL;

int WinMain(...) {
   if(main)
       main(); // call the user defined funcion
   while(!done) {
       if(messageWaiting()) {
           processMessage();
       }
   }

}

Why? because I want to deploy a window wrapper and avoid to have the user writting the WinMain entry point. But a DLL project have a DLL main and a win32 project that uses a DLL complaim if linker doesnt find a winMain entry point.

Is there a know solution for this kind of arrange?

like image 783
Ruben Trancoso Avatar asked Oct 14 '22 14:10

Ruben Trancoso


2 Answers

Every Win32 application must have an entry point (usally WinMain). So you can't put the entry point in the DLL, because it's not really part of the EXE. However the entry point can be in a statically linked library. When the static library gets linked, the entry point becomes part of the EXE.

But my suggestion is to avoid all this complexity. Just make the users of your DLL call something like this:

int WinMain( HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow )
{
    return WrapperDllMain( hInstance, hPrev, lpCmdLine, nCmdShow, &user_main );
}

The code is simple and easy to write. It's not much effort on the part of the DLL users. You have total control over the message loop (and the entire process lifetime).

like image 165
Victor Arndt Mueller Avatar answered Oct 19 '22 03:10

Victor Arndt Mueller


You can't implement an application's WinMain() entry point inside a separate DLL. The application must implement its own entry points, or else the linker will complain, as you have already discovered. The application's entry point can call functions that are in the DLL, ie:

--- app ---

#include "dllheader.h" 

int user_main()
{
  ...
}

int WinMain(...)
{
  return dll_main(&user_main);
}


--- dll ---

int dll_main(void (*user_main)())
{
  if(user_main)
    user_main(); // call the user defined funcion

  while(!done)
  {
    if(messageWaiting())
    {
      processMessage();
    }
  }
  return 0;
}
like image 34
Remy Lebeau Avatar answered Oct 19 '22 02:10

Remy Lebeau