【问题标题】:WinMain exported from a DLL从 DLL 导出的 WinMain
【发布时间】:2010-12-27 16:31:21
【问题描述】:

我正在尝试将 WinMain 函数隐藏在 DLL 中,以避免一遍又一遍地再次输入大量代码。

我从 DLL 中导出 wWinMain,将其声明为

extern "C" int WINAPI wWinMain( ... ) { // repetitive code here }

并使用了链接器选项/EXPORT:wWinMain,但是当我尝试在另一个项目中使用导入库时出现错误

LIBCMTD.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function __tmainCRTStartup

备注我确实想使用 GUI 界面,我知道这是定义 main 而不是 WinMain 函数时的常见错误。另外,我在两个项目中都启用了 UNICODE 支持。我该怎么办?

【问题讨论】:

  • 也许我在这里遗漏了一些非常简单的东西,但在我看来你有一个命名问题。您导出的函数的名称为wWinMain,启动代码正在寻找一个名为WinMain 的符号。解决该问题的另一种方法是在主程序中创建一个标准的WinMain 函数,它只调用DLL 中的wWinMain 函数。
  • 为什么要将 wWinMain 放在 DLL 中?这真的没有意义。如果它是供 DLL 使用的,则不应将其称为 wWinMain 或将其导出。如果它是给调用者的,......调用者调用 WinMain 已经太晚了,如果你想让他们把这个函数作为某种插入入口点调用,你应该调用它MyMain,而不是已经存在的东西由标准 Windows 开发保留。

标签: winapi linker-errors dllexport winmain


【解决方案1】:

这是不可能的,链接器只能将 EXE 的入口点设置为 EXE 内部的函数。将 DLL 中的 wWinMain() 重命名为其他名称。在链接到 EXE 的源代码文件中编写 wWinMain(),只需调用 DLL 的导出函数即可。

【讨论】:

    【解决方案2】:
    //  ...somewhere in a .cpp file within my .dll's sources...
    #define WinMain WinMainOld // ...to suppress Win32 declaration of WinMain
    #include <windows.h>
    #undef WinMain // ...so that WinMain below is not replaced
    .   .   . 
    #pragma comment(linker, "/export:_WinMain@16") // ...to export it from .dll
    extern "C" // ...to suppress C++ name decoration
    int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                         PSTR pCmdLine, int nCmdShow)
    {
        .   .   .
    }
    

    【讨论】:

      【解决方案3】:

      您应该在 DLL 中使用 WinMain 吗?不应该是 DllMain 吗?

      【讨论】:

        【解决方案4】:

        如果你想调用dll的WinMain,你需要替换CRTWinMainStartup函数(你喜欢的CRT lib中的_tmainCRTStartup),并让它调用你导出的WinMain,这会阻止链接器寻找本地WinMain并且仍然保持程序的正确流程(CRT启动的源代码应该在任何编译器的crt源代码中)

        【讨论】:

          【解决方案5】:

          我找到了一种将 WinMain 放入 DLL 的方法。

          • 您需要使用 WinMain 而不是 wWinMain(我不知道为什么)
          • 将 def 文件附加到您的项目中,
            在 def 文件中附加 EXPORTS WinMain。 像这样

            出口

            WinMain

            从观察来看,都需要生成导出函数,不仅仅是WinMain。

            经测试,__declspec(dllexport)的方式对WinMain无效。

          • 将您的程序链接到 DLL 库 使用 #pragma comment(lib, "testDll.lib") 或修改项目中的设置。

          【讨论】:

            【解决方案6】:
            EXPORT int WINAPI _WinMain_(int (*_main_)(int argc, char **argv), HINSTANCE hInst, HINSTANCE    hPrevInstance, LPSTR commandLine, int nCmdShow);
            int _XMain( int argc, char **argv );
            
            #define XMain   WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR commandLine, int nCmdShow)\
            {return _WinMain_( _XMain, hInst, hPrevInstance, commandLine, nCmdShow );}  \
            int _XMain
            

            然后_WinMain_() 致电或安排_XMain()

            在您的应用程序源中结束:

            int XMain( int argc, char **argv )
            {
            }
            

            【讨论】:

            • 问题中没有任何内容表明需要回调应用程序代码。所以我会取出宏的int _XMain 部分和额外的参数。不过,其余的都是合理的。宏有助于很好地处理样板文件。
            猜你喜欢
            • 1970-01-01
            • 2010-09-06
            • 1970-01-01
            • 1970-01-01
            • 2011-03-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多