如何解读WinMain文档?含[in]属性的WinMain编译报错如何解决?
关于WinMain函数[in]属性及编译错误的问题
我查看了WinMain的官方文档,其函数声明如下:
int __clrcall WinMain( [in] HINSTANCE hInstance, [in] HINSTANCE hPrevInstance, [in] LPSTR lpCmdLine, [in] int nShowCmd );
我有两个问题:
- 方括号标注的[in]属性是否为可选?若可选,正确写法是怎样的?
- 我在Visual Studio中使用编译选项:
编写了如下代码:/clr /permissive- /Zc:twoPhase-
但编译失败,报错信息如下:#include <Windows.h> int __clrcall WinMain( [in] HINSTANCE hInstance, [in] HINSTANCE hPrevInstance, [in] LPSTR lpCmdLine, [in] int nShowCmd ) { return 0; }
请问该如何解决这些问题?C2373 WinMain': redefinition; different type modifiers C2337 'in': attribute not found E0337 linkage specification is incompatible with previous "WinMain" (declared at line 1033) WinBase.h E0147 declaration is incompatible with "int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)" (declared at WinBase.h)
问题解答
一、[in]属性的说明
[in]是微软的SAL代码标注,属于静态分析工具的提示语法,不属于C++标准内容:
- 它完全可选,去掉后不影响函数编译和运行,只是失去了静态分析时的参数用途提示。
- 若要保留,需确保项目启用了SAL支持(Visual Studio默认支持),且在
/clr模式下建议使用__in替代[in],兼容性更好;或者直接包含<sal.h>(通常<Windows.h>已间接包含)。
二、编译错误的解决步骤
你的错误核心是调用约定冲突、SAL标注不兼容和重复定义,按以下方式修复:
1. 修正WinMain的调用约定
Windows系统原生WinMain的标准调用约定是__stdcall,头文件中通过WINAPI宏定义了这个约定。你写的__clrcall是托管代码的调用约定,和头文件中的声明冲突,导致重定义错误。
正确写法:
#include <Windows.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) { return 0; }
2. 处理SAL标注(可选)
如果一定要保留参数用途提示,改用__in标注(兼容/clr模式):
#include <Windows.h> int WINAPI WinMain( __in HINSTANCE hInstance, __in HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd ) { return 0; }
3. 关于/clr编译选项的说明
/clr用于编译C++/CLI托管代码,若你只是写原生Win32程序,建议移除这个选项;若确实需要开发托管程序,建议使用int main()作为入口,或者遵循C++/CLI的入口规范,避免和原生WinMain的声明冲突。
内容的提问来源于stack exchange,提问作者sanitizedUser
相关产品推荐
相关产品推荐

