0

我有以下代码:

#include <stdio.h>

int main()
{
    printf ("hello world\n");
    return 0;
}

在 Windows 7 x86 上使用 MSVC++ 10.0,我在命令行上编译它如下:

cl.exe simple.cpp

这将生成 simple.exe(编译器自动调用链接器)并且可执行文件按预期显示“hello world”消息。当我查看带有depends.exe的可执行文件时,它显示kernel32.dll是唯一的依赖项。当我转储 kernel32.dll 库的内容时,没有显示 printf。

VC++ 是否采用了某种优化,以便 printf 以某种方式直接包含在最终的可执行文件中?如果是这样,它是如何记录的,是否记录在任何地方?

4

3 回答 3

2

MS VC 将“默认”库的名称嵌入到大多数目标文件中。除非您使用链接器的-nodefaultlib选项另外指定,否则该库(或那些库)将被链接。如果您单独使用它,它不会链接任何默认库。或者,您可以指定一个特定的库,例如,在这种情况下,它会链接您在此处指定的库之外的-nodefaultlib:mylib.lib所有默认库。

要使用您的示例,如果您使用:

cl simple.c

它将正确编译和链接。但是,如果您使用:

cl simple.c -link -nodefaultlib

你会得到:

simple.obj:错误 LNK2019:未解析的外部符号 printf 在函数 main
LINK 中引用:错误 LNK2001:未解析的外部符号 mainCRTStartup
simple.exe:致命错误 LNK1120:2 个未解析的外部

为了完整起见,您还可以使用编译器的/Zl开关来创建对象,而无需嵌入任何库的名称。这(主要)用于创建静态库,因此它们不会嵌入可能与您构建使用您的库的代码发生冲突的库的名称。

于 2010-11-14T17:55:19.977 回答
1

libc.lib不再使用。

在 VC++ 10 上静态或动态包含 C 运行时库 (CRT) 的选项在此处记录。您可以在“项目选项”中选择您需要/想要的那个。

于 2010-11-14T15:45:11.520 回答
0

printf(实际上是 fprintf 到 stdout)以及其他“标准”函数 malloc、exit 等与 libc.lib 静态链接,这就是为什么您在任何地方都看不到它作为 dll 的原因。

于 2010-11-14T15:43:02.103 回答