WinAPI 如何确保在未实现 WinMain 时编译失败

How Does WinAPI ensure compilation fail when WinMain is not implemented

本文关键字:实现 WinMain 失败 编译 何确保 确保 WinAPI      更新时间:2023-10-16

当您在Visual Studio中创建Win32项目并且未定义WinMain函数时,您会收到编译错误:

错误

1 错误 LNK2019:函数___tmainCRTStartup中引用未解析的外部符号_WinMain@16

如何设计/实现此 API 设置以确保用户在不实现WinMain的情况下永远无法创建 Win32 应用程序?我正在创建一个 API,当用户未正确使用 API 或未实现基本功能时,我还想输入编译错误。

我想使用类似内容的一个例子是:用户必须实现一个App类(基类或继承类)。因此,如果我可以在编译时以某种方式检测到 App 类尚未实现,我也可以抛出编译错误。

WinAPI 的实现是否像尚未实现的前向声明函数一样简单(这可确保编译失败)?即,

// Forward declaration with, intentionally, no function implementation
int APIENTRY _tWinMain(_In_ HINSTANCE  hInstance, _In_opt_ HINSTANCE  hPrevInstance, _In_ LPTSTR  lpCmdLine, _In_ int  nCmdShow);

启动程序时,操作系统加载模块,然后调用初始化代码。哪个符号带有初始化代码(入口点)可以更改,但通常它是类似于winMainCRTStartupmainCRTStartup(如果我没记错的话)。现在,该函数由编译器供应商提供并链接到您的程序中。它首先调用初始化代码,例如全局变量的构造函数,然后委托给各种形式的main()winMain()。这也是编译失败的原因:由于初始化代码始终包含在内(通过其外部可见的入口点),并且它始终调用相应的 main 函数,因此缺少 main 函数将导致链接器错误。

请注意,一个简单的声明是不够的(你可以尝试一下),你必须确保它声明的函数被实际使用。

关于你生成错误的方法,我认为这是不可行的,至少在编译时是不可行的。如果可能的话,我也会尽量避免使用库的这种严格的约束。为什么应用程序内不应该有多个这样的类或库的多个用途?如果约束确实有意义,请考虑使用类似于许多窗口库的技术,这些库提供注册用户编写的实例的全局函数。然后,您可以向代码添加assert()实例已注册的检查。

解决方案确实和您期望的一样简单。在代码中,从 App 派生,如果未提供该基库,编译器将抱怨。

为此,您必须提供源代码:如果没有编译器输入,则无法获得编译器错误,并且编译器的输入是源代码。话虽如此,这并不意味着您必须将所有代码作为源代码发布。您可能会提供具有class Derived : public App { ... }但其方法只是(内联)调用 .自由。