从 DLL 导出的 WinMain

发布于 2024-10-09 11:43:27 字数 461 浏览 7 评论 0原文

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

从 DLL 导出

我通过将 wWinMain 声明为extern "C" int WINAPI wWinMain( ... ) { // 这里重复代码 }

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

LIBCMTD.lib(wincrt0.obj) : 错误 LNK2019: 无法解析的外部符号 _WinMain@16 在函数 __tmainCRTStartup 中引用

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

I am trying to hide the WinMain function inside a DLL in order to avoid typing again much of the code over and over again.

I exported wWinMain from the DLL by declaring it as


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

and used the linker option /EXPORT:wWinMain, but when I try to use the import library in another project I get the error


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

Remark I do want to use the GUI interface and I know this is common error when you define a main instead of a WinMain function. Also, I enabled the UNICODE support in both projects. What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柏拉图鍀咏恒 2024-10-16 11:43:27

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

This is not possible as-is, the linker can only set the entrypoint for an EXE to a function that's inside the EXE. Rename the wWinMain() in the DLL to something else. Write a wWinMain() in a source code file that gets linked into your EXE, simply call the DLL's exported function.

咽泪装欢 2024-10-16 11:43:27
//  ...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)
{
    .   .   .
}
//  ...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)
{
    .   .   .
}
余生共白头 2024-10-16 11:43:27

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

Should you be using WinMain in a DLL? Should it not be DllMain?

傲世九天 2024-10-16 11:43:27

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

If you want to call the WinMain of the dll, you need to replace the CRTWinMainStartup function(_tmainCRTStartup in your liked CRT lib), and make it call your exported WinMain, this stops the linker looking for a local WinMain and still keeps correct flow of the program(the source for the CRT startups should be in the crt source of any compiler)

在梵高的星空下 2024-10-16 11:43:27

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

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

    <块引用>

    出口

    <块引用>

    WinMain


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

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

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

I find one way to put WinMain inside DLL.

  • You need to use WinMain instead of wWinMain (I don't know why)
  • Append a def file into your project and,
    append EXPORTS WinMain in def file.
    Like this

    EXPORTS

    WinMain

    From the observation, all need exported functions generated, not only WinMain.

    After test, the way of __declspec(dllexport) is invalid for WinMain.

  • Link your program to the DLL library
    use #pragma comment(lib, "testDll.lib")
    or modify setting in the project.
稀香 2024-10-16 11:43:27
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 )
{
}
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

Then _WinMain_() calls or schedules _XMain().

Over in your application source:

int XMain( int argc, char **argv )
{
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文