我正在尝试使用 Windows SDK 命令提示符编译一个简单的 C Windows API 程序。
以下是该计划的摘录:
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
[...]
RegisterClass(&wc);
hwnd = CreateWindow("test", NULL, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
[...]
当我使用它编译时
cl test.c
在 Windows SDK 命令提示符中,它给了我很多链接器错误,如下所示:
test.obj : error LNK2019: unresolved external symbol __imp_CreateWindowExA referenced in function WinMain
test.obj : error LNK2019: unresolved external symbol __imp_RegisterClassA referenced in function WinMain
至少有两个问题。
-
链接器告诉您有一个“未解析的外部符号”。这意味着它找不到您尝试调用的函数的定义。在这种情况下,有两个这样的未定义函数:CreateWindowExA
and RegisterClassA
.
显然,这些函数的定义不是在您的代码中找到,而是在 Windows API 库中找到,因此您需要通知链接器在哪里可以找到这些定义。
SDK 附带存根 (*.lib
) 文件,其中包含链接器使用的信息,以便链接器可以在运行时在 Windows DLL 中找到正确的函数定义。您需要指示链接器在哪里可以找到这些*.lib
files.
有几种不同的策略可以做到这一点:
-
简单(尽管不可移植)的方法是插入#pragma
语句到源文件中,指示编译器留下链接器识别的注释。例如,
#pragma comment(lib, "user32")
自动链接到user32.lib
,这是存根文件user32.dll
.
-
或者,您可以将命令行上的参数传递给cl.exe
。但是,如果您不使用 MSBuild 或某种 make 文件,那么这很快就会变得非常复杂。在这种情况下,您需要将命令行修改为(至少):
cl test.c user32.lib
这两个选项自然假设您的 Windows SDK 目录已添加到路径中。我很确定安装程序会自动为您完成此操作,但我并不肯定。如果没有,或者您已从路径中删除了这些文件,则需要使用完全限定的路径*.lib
命令行上的文件。
Reading 可能的编译器选项的文档是一个很好的起点。或者更好的是,如果您不熟悉 Windows 编程,可以使用 Visual Studio 等环境来自动将所有这些内容组合在一起。一旦您了解了发生了什么,就可以查看 Visual Studio 运行的命令行是什么,并一点一点地剖析它。
-
下一个问题是你正在编译withoutUnicode 定义的,并且因为ANSI 是默认值,Windows 头文件中的所有宏都解析为调用A
所有 SDK 功能的后缀版本。这可能不是您想要的。 Windows 完全采用 Unicode 已经有十多年了,所有新应用程序都应该构建为 Unicode。 Unicode 版本有一个W
后缀附加到他们的名字上。
同样,您可以通过向源文件添加行或向命令行添加参数来显式指示编译器使用 Unicode 进行构建。
在这种情况下,最简单的方法可能就是添加
#define UNICODE
到源文件的顶部before #include <windows.h>
。正如我们在上面看到的,在 Visual Studio 环境中,UNICODE
除非您明确更改项目设置以瞄准其他目标,否则会自动为您定义。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)