WinMain 重新定义

Posted

技术标签:

【中文标题】WinMain 重新定义【英文标题】:WinMain redefinition 【发布时间】:2013-01-20 19:35:15 【问题描述】:

我刚开始使用 C++,遇到了一个我无法修复的错误。

这是我到目前为止的所有代码(甚至无法让 hello world 工作):

#include "stdafx.h"
#include <windows.h>


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
               LPSTR lpCmdLine, int nCmdShow)

                   MessageBox(NULL, L"Hello World!",
                       L"Hello World!",
                       MB_ICONEXCLAMATION | MB_OK);
                   return 0;

但是当我尝试运行它时会出现这个错误:

Test.cpp(11):错误 C2373:'WinMain':重新定义;不同的类型修饰符 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winbase.h(2588) :参见“WinMain”声明

当我查看 WinMain 的声明时,我看到每个参数前都有一个“__in”。我尝试添加它,但没有运气。我也尝试用 CALLBACK 替换 WINAPI,但也没有用。

【问题讨论】:

尝试使用注释掉的stdafx.h 包含构建 - 那里可能有一些宏导致问题。你用的是什么版本的VS?你能发布构建日志吗? 这是 LPWSTR,不是 LPSTR。 @HansPassant 根据文档,LPSTR 是正确的 - msdn.microsoft.com/en-us/library/ms633559(VS.85).aspx 尝试使用INT WinMain(...)... 而不是int WINAPI WinMain(...)... @Michael Burr,我试过了,但没用。 【参考方案1】:

简单的解决办法是

    使用标准的main 函数

像这样:

#undef UNICODE
#define UNICODE
#incude <windows.h>

int main()

    MessageBox(
        0,
        L"Hello World!",
        L"Hello World!",
        MB_ICONEXCLAMATION | MB_SETFOREGROUND
        );

现在您唯一的问题是使用 Microsoft 的工具集将其构建为 GUI 子系统应用程序,这在这方面有点迟钝(GNU 工具链没有这样的问题)。

为此,对于 Microsoft 的 link,使用此链接器选项(除了选择 GUI 子系统之外):/entry:mainCRTStartup

请注意,您可以将该选项放在名为 LINK 的环境变量中。

编码愉快! :-)

【讨论】:

你也可以告诉 Visual Studio 编译一个控制台应用程序,它会自动切换到 main() 作为入口点。关于 UNICODE 宏的定义/取消定义,通过在项目设置的常规选项卡中设置字符集选项也更容易实现。 @doomster:我很确定 OP 不想要控制台窗口。关于选择宏集(UNICODE)的“更容易”,不,这是一个非常糟糕的主意。代码应该独立存在,以便可以轻松地在项目之间移动或复制,或使用其他工具构建,而不依赖于某些特定于版本的 Visual Studio 配置文件中指定的细节。此外,在 Visual Studio 项目配置中单击自己的方式绝对不会比在文件顶部键入两个短行更容易。 更典型的链接器选项是设置/SUBSYSTEM:WINDOWS 只是好奇:开头的L是什么意思? @Cheersandhth.-Alf 但是 WinMain 函数的重点不是为程序实例提供句柄,因此您可以执行诸如阻止打开多个实例之类的操作,并使用命令行选项?这些选项可以通过标准的 main 函数来完成,但是我将如何完成前者呢?【参考方案2】:

WinMain 是一个 C 函数,因此你需要用 extern "C" 包装它

#include "stdafx.h"
#include <windows.h>

extern "C"


    int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
               LPSTR lpCmdLine, int nCmdShow)
    
                   MessageBox(NULL, L"Hello World!",
                       L"Hello World!",
                       MB_ICONEXCLAMATION | MB_OK);
                   return 0;
    

【讨论】:

我在 C++ 上使用 WinMain 和 VS2017,但我重新分解了很多代码,现在它不起作用。我不知道我做了什么。

以上是关于WinMain 重新定义的主要内容,如果未能解决你的问题,请参考以下文章

未定义对“WinMain@16”的引用?

c++主函数如何调用"WinMain"函数

WIN32 SDK API的基础问题(窗口显示)

winmain中一使用这个函数MyRegisterClass提示无法重载

关于VC++的Winmain函数(WINAPI是啥?)

WinMain与wWinMain,win32的字符集问题