我试图了解 C/C++ 中的编译和链接过程。我知道源文件首先由编译器转换为目标文件。然后链接器从目标文件生成库或可执行文件。
我试图首先阅读目标文件中的信息。这是我为实验编写的程序。
函数.h
#include <iostream>
void beautifulprint(char *str);
函数cpp
#include "stdafx.h"
#include "func.h"
using namespace std;
void beautifulprint(char *str) {
cout << "*** " << str << " ***" << endl;
}
测试应用程序.cpp
#include "stdafx.h"
#include "func.h"
int _tmain(int argc, _TCHAR* argv[])
{
beautifulprint("Hello, world!");
return 0;
}
在 VS 2010 中构建项目后,我得到了 func.obj。我假设在 func.obj 中的某个地方应该有 beautifulprint 函数的引用。我为 func.obj 的调试和发布版本运行了以下内容
dumpbin /HEADERS func.obj > funchead.txt
下面是输出。
调试版本(不包括完整输出,因为它非常大)
...
SECTION HEADER #41
.text name
0 physical address
0 virtual address
78 size of raw data
5B94 file pointer to raw data (00005B94 to 00005C0B)
5C0C file pointer to relocation table
0 file pointer to line numbers
A number of relocations
0 number of line numbers
60501020 flags
Code
COMDAT; sym= "void __cdecl beautifulprint(char *)" (?beautifulprint@@YAXPAD@Z)
16 byte align
Execute Read
SECTION HEADER #42
.debug$S name
0 physical address
0 virtual address
E8 size of raw data
5C70 file pointer to raw data (00005C70 to 00005D57)
5D58 file pointer to relocation table
0 file pointer to line numbers
7 number of relocations
0 number of line numbers
42101040 flags
Initialized Data
COMDAT (no symbol)
Discardable
1 byte align
Read Only
...
发布版本(完整输出!)
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file func.obj
File Type: ANONYMOUS OBJECT
ANON OBJECT HEADER VALUES
1 version
14C machine (x86)
50213733 time date stamp Tue Aug 07 16:41:39 2012
ClassID: {0CB3FE38-D9A5-4DAB-AC9B-D6B6222653C2}
2D1 size
0 flags
这是我的问题。不出所料,func.obj Debug 版本有对 beautifulprint 的引用。但令我惊讶的是,Release 版本中没有提到 beautifulprint?链接器如何知道此函数存在于目标文件中。
另外为什么调试 obj 版本具有来自 iostream 的功能?这些不应该出现在某个标准库而不是这个obj中吗?
编辑:我直接在 VS 2010 中以 Hex 格式打开了 release func.obj。我在右侧 (ASCII) 列中搜索了 beautifulprint 及其存在。这意味着引用存在。为什么垃圾箱不显示它?我需要一些工具来以人类可读的格式查看它。