【问题标题】:Encapsulate Windows message loop into a DLL将 Windows 消息循环封装到 DLL 中
【发布时间】:2009-07-21 00:10:24
【问题描述】:

我想要一个带有窗口创建和管理代码的 DLL,开发人员只需添加一个命名的 main.h 标头并加载 DLL 即可实例化一个窗口。

#include "dllheader.h" 

void user_main();

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

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

在 DLL 端,代码应该是这样的

void (*main)() = NULL;

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

}

为什么?因为我想部署一个窗口包装器并避免让用户编写 WinMain 入口点。但是一个 DLL 项目有一个 DLL main 和一个 win32 项目,如果链接器找不到 winMain 入口点,则使用 DLL 抱怨。

这种安排是否有已知的解决方案?

【问题讨论】:

    标签: c++ winapi dll


    【解决方案1】:

    每个 Win32 应用程序都必须有一个入口点(通常是 WinMain)。所以你不能把入口点放在 DLL 中,因为它并不是 EXE 的一部分。但是入口点可以在静态链接库中。当静态库被链接时,入口点成为 EXE 的一部分。

    但我的建议是避免所有这些复杂性。只需让您的 DLL 的用户调用如下内容:

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

    代码简单易写。对 DLL 用户而言,这并不费力。您可以完全控制消息循环(以及整个进程生命周期)。

    【讨论】:

      【解决方案2】:

      您不能在单独的 DLL 中实现应用程序的 WinMain() 入口点。应用程序必须实现自己的入口点,否则链接器会抱怨,正如您已经发现的那样。应用程序的入口点可以调用 DLL 中的函数,即:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-04
        • 2011-07-06
        • 2013-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多