??xml version="1.0" encoding="utf-8" standalone="yes"?>
typedef int (AObj::*pfun)();
pfun pf_protected1 = NULL;
pfun pf_protected2 = NULL;
pfun pf_private1 = NULL;
pfun pf_private2 = NULL;
class AObj
{
public:
AObj(){};
static int a_static_fun()
{
pf_protected1 = &AObj::a_protected_fun1;
pf_protected2 = &AObj::a_protected_fun2;
pf_private1 = &AObj::a_private_fun1;
pf_private2 = &AObj::a_private_fun2;
return -1;
}
int a_public_fun1()
{
return 0;
}
int a_public_fun2()
{
return 1;
}
protected:
int a_protected_fun1()
{
return 2;
}
int a_protected_fun2()
{
return 3;
}
private:
int a_private_fun1()
{
return 4;
}
int a_private_fun2()
{
return 5;
}
};
int test1(char* p);
int test2(char* p);
int test1(char* p)
{
test2(p);
return 1;
}
int test2(char* p)
{
for (int i = 0; i < 172; i++)
{
*p++ = '\0';
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
AObj obj;
AObj::a_static_fun();
printf("obj: %p\n", &obj);
printf("AObj::a_static_fun %p\n", &AObj::a_static_fun);
printf("AObj::a_public_fun1 %p\n", &AObj::a_public_fun1);
printf("AObj::a_public_fun2 %p\n", &AObj::a_public_fun2);
printf("AObj::a_protected_fun1 %p\n", pf_protected1);
printf("AObj::a_protected_fun2 %p\n", pf_protected2);
printf("AObj::a_private_fun1 %p\n", pf_private1);
printf("AObj::a_private_fun2 %p\n", pf_private2);
//char szbuf[2];
//sprintf(szbuf, "%d", 3.54f);
//test1(szbuf);
return 0;
}
今天写了一D代? 是在Windows下编辑的, 保存后放在linuxpȝ下编?
gcc和cc都生以下的警告:
a.h:1:2: warning: no newline at end of file
后来发现解决q个问题产生的原因是源文件的最后一行没有回车符造成? 解决的办法很? 在最后一行敲一个回? 然后保存, 重新~译.
说明Q?/strong>
Visual C++ 1.0Q集成了MFC 2.0Q是Visual C++W一代版本,1992q推出,可同时支?6位处理器?2位处理器版,可算是Microsoft C/C++ 7.0的更新版本?br>
Visual C++ 1.5Q集成了MFC 2.5Q增加了“目标文g链接嵌入 (OLE)2.0和支持MFC的开攑ּ数据库链接(ODBCQ。这个版本只?6位的Q也是第一个以CD-ROMY件蝲体的版本。这个版本也没有所?#8220;标准?#8221;。它是最后一个支?6位Y件编E的软gQ也是第一个支持基于x86机器?2位编EY件?br>
Visual C++ 2.0Q集成了MFC 3.0Q第一个只发行32位的版本。这个版本提前发行了Q几乎成了一?#8220;丢失的版?#8221;。这是因为那个时候Windows 95Q开发代码ؓ"Chicago"Q还没有发行Q而Windows NT又只占有很小的市Z额。该版本用户可以通过微Y公司的订阅服务(Microsoft Subscription ServiceQ升U至2.1?.2版本。微软公司在q个版本中集成ƈ升了Visual C++ 1.5Q作?.0版本QVisual C++ 1.5升后版本号Q?.51Q以?.1版本QVisual C++ 1.5升后版本号Q?.52Q的一部分。Visual C++ 2.x附带?6位和32位版本的CDKQ同时支持Win32s的开发。Visual C++ 2.2及其后箋版本不再升Visual C++ 1.5Q尽它一直被集成至Visual C++ 4.xQ。尽出生的比Windows 95早,q个版本的发行日期还是非常接qWindows 95Q可是当Windows 95发行ӞVisual C++ 4.0也已l发行了。因此很多程序开发者直接从1.xq渡?.0Q把2.x跌M?br>
Visual C++ 4.0Q集成了MFC 4.0Q这个版本是专门为Windows 95以及Windows NT设计的。用户可以通过微Y公司的订阅服务(Microsoft Subscription ServiceQ升U至4.1?.2版本Q此版本不再支持Win32s开发)?br>
Visual C++ 5.0Q集成了MFC 4.21Q是4.2版以来比较大的一ơ升U?br>
Visual C++ 6.0Q集成了MFC 6.0Q于1998发行。发行至今一直被q泛地用于大大小的目开发。但是,q个版本在Windows XP下运行会出现问题Q尤其是在调试模式的情况下(例如Q静态变量的值ƈ不会昄Q。这个调试问题可以通过打一个叫“Visual C++ 6.0 Processor Pack”的补丁来解决。奇怪的是,q个|页用户也必运行Windows 98、Windows NT 4.0、或Windows 2000?br>
Visual C++ .NET 2002Q也即Visual C++ 7.0Q,?002q发行,集成了MFC 7.0Q支持链接时代码生成和调试运行时查。这个版本还集成了Managed Extension for C++Q以及一个全新的用户界面Q与Visual Basic和Visual C#qQ。这也是Z么Visual C++ 6.0仍然被广泛用的一个主要原因?br>
Visual C++ .NET 2003Q也即Visual C++ 7.1Q,集成了MFC 7.1Q于2003q发行,是对Visual C++ .NET 2002的一ơ重大升U?br>eMbedded Visual C++Q用于Windows CE操作pȝ。Visual C++作ؓ一个独立的开发环境被Microsoft Visual Studio 2005所替代?br>
Visual C++ 2005Q也即Visual C++ 8.0Q,集成了MFC 8.0Q于2005q?1月发布。这个版本引q了对C++/CLI语言和OpenMP的支持?br>
Visual C++ 2008Q也即Visual C++ 9.0Q,?007q?1月发布。这个版本支?NET 3.5?br>
Visual C++ 2010Q也即Visual C++ 10.0Q,?010q发布,是目前最新的版本。Visual C++开发团队考虑使用SQL Server Compact格式的数据库来存储源码的相关信息[1].本版也加入了C化的C++q行q算?Parallel Patterns LibraryQ部分支持C++0x。本版徏构于.NET 4.0之上Q但仍支持机器码的编译?/p>
]]>
1Q?nbsp;PCH文g
预编译头文g(一般扩展名?PCH),是把一个工E中较稳定的代码预先~译好放在一个文?.PCH)?q些预先~译好的代码可以是Q何的C/C++代码--甚至可以是inline函数,只它们在整个工程中是较ؓE_?卛_工程开发过E中不会l常被修改的代码.
Z么需要预~译头文?一a以蔽?提高~译速度.一般地,~译器以文g为单位编?如果修改了一工程中的一个文件则所有文仉要重新编?包括头文仉的所有东?eg.Macro?Preprocessor预处?,而VCE序?q些头文件中所包括的东西往往是非常大?~译之将占很长的旉.但它们又不常被修?是较E_?为单独的一个小文g而重新编译整个工E的所有文件导致编译效率下?因此引入?PCH文g.
如何使用预编译头文g以提高编译速度?要用预~译头文?必须指定一个头文g(.H),它包含我们不会经怿改的代码和其他的头文?然后用这个头文g(.H)来生成一个预~译头文?.PCH)VC默认的头文g是StdAfx.h,因ؓ头文件是不能~译?所以我们还需要一?CPP文g来作桥梁,VC默认的文件ؓStdAfx.cpp,q个文g里只有一句代码就?Qinclude "StdAfx.h".接下来要用它生成.PCH文g,涉及到几个重要的预编译指?/Yu,/Yc,/Yx,/Fp.单地?/Yc是用来生?PCH文g的编译开?在Project->setting->C/C++的Category里的Precompiled Header,然后在左边的树Ş视图中选择用来~译生成.PCH文g?CPP文g(默认即StdAfx.cpp)你就可以看到/Ycq个开?它表C个文件编译了以后是否生成.PCH文g(可能/Yc的c表示create)./Fp指o指定生成?PCH文g的名字及路径(可能/Fp的p代表path)./Yu的u即use使用,工程中只要包括了.H文g的文仉会有q个/Yu指o.如果选择自动Automatic...的话则原来ؓ/Yc的地方就换成?Yx指o.如果选择自动,则每ơ编译时~译器会看以前有没有生成q?PCH文g,有则不现生成否则再ơ编译?PCH文g.
注意:
A,实际?由Appzard目向导生成的默认的头文件及CPP文gStdAfx.h和StdAfx.cpp可以是Q何名字的.原因很简?但如果你要这样做p记得修改相应的Project->setting...下的几个预编译指?/Yc,/Yu,/Yx,/Fp)的参?
B.在Q何一个包括了要预编译的头文件而用了.PCH文g的工E文件的开?一定必要是在最开?你要包含那个指定生成.PCH文g?H文g(通过.CPP文g包括,默认为StdAfx.cpp),如果没包括将产生我最开头生的错误.如果不是在最开头包括将产生让你意想不到的莫名其妙错?如若不信,盍ؓ试之?
C.预编译文?PCH生成之很耗时?而且生成之后它也很占盘I间,常在5
D.如果丢了或删?PCH文g而以后要再修改工E文件时,可将指定?Yc?CPP文g(默认为StdAfx.cpp)重新~译一ơ即可再ơ生?PCH文g,不用d的按F7或Rebuild All
2Q?nbsp;NCB文g
.ncb 无编译浏览文?no compile browser)。当自动完成功能出问题时可以删除此文件。build后会自动生成
3Q?nbsp;OBJ文g
目标文gQ一般是E序~译后的二进制文Ӟ再通过链接器和资源文g链接成exe文g了?/p>
OBJ只给ZE序的相对地址Q而EXE是绝对地址?/p>
4Q?nbsp;PDB文g
E序数据?(PDB) 文g保存着调试和项目状态信息,使用q些信息可以对程序的调试配置q行增量链接。当?/ZI ?/ZiQ用?C/C++Q生成时Q将创徏一?PDB 文g?/p>
?Visual C++ 中,/Fd 选项用于命名q译器创徏的PDB 文g。当使用向导在Visual Studio 中创建项目时Q?Fd 选项被设|ؓ创徏一个名?project.PDB ?PDB?/p>
如果使用生成文g创徏 C/C++ 应用E序Qƈ指定 /ZI ?/Zi 而不指定 /Fd Ӟ则最l将生成两个 PDB 文gQ?/p>
*VC80.PDB Q更W统地说是 VCx0.PDBQ其?x 表示 Visual C++ 的版本。)该文件存储各?OBJ 文g的所有调试信息ƈ与项目生成文仉留在同一个目录中?/p>
*project.PDB 该文件存?.exe 文g的所有调试信息。对于C/C++Q它ȝ?\debug 子目录中?/p>
每当创徏 OBJ 文gӞC/C++ ~译器都调试信息合q到 VCx0.PDB 中。插入的信息包括cd信息Q但不包括函数定义等W号信息。因此,即每个源文仉包含公共头文Ӟ?<windows.h>Q,q些头文件中?typedef 也只存储一ơ,而不是在每个 OBJ 文g中都存在?/p>
链接器将创徏 project.PDBQ它包含目?EXE 文g的调试信息。project.PDB文g包含完整的调试信息(包括函数原型Q,而不仅仅是在 VCx0.PDB 中找到的cd信息。这两个 PDB 文g都允许增量更新。链接器q在其创建的 .exe ?.dll 文g中嵌?.pdb 文g的\径?/p>
Visual Studio 调试器?EXE ?DLL 文g中的PDB 路径查找 project.PDB 文g。如果调试器在该位置无法扑ֈ PDB 文g或者如果\径无效(例如Q如果项目被UdC另一台计机上)Q调试器搜索包?EXE 的\径,卛_“选项”对话框(“调试”文g夹,“W号”节点Q中指定的符可\径。调试器不会加蝲与所调试的二q制不匹配的 PDB?/p>
5Q?nbsp;ILK文g
在增量链接时QLINK 更新在第一ơ增量链接期间创建的 .ilk 状态文件。该文g?.exe文g?.dll 文gh相同的基名称Qƈh扩展?.ilk。在后面的增量链接期_LINK 更新 .ilk 文g。如果缺?.ilk 文gQ则 LINK 执行完全链接q创建新?.ilk 文g。如?.ilk 文g无法使用Q则 LINK 执行非增量链接。有兛_量链接的详细信息Q请参见渐进式链?/INCREMENTAL) 选项?/p>
6Q?nbsp;MAP文g
Windows和Linuxpȝ下都有map文gQmap文g一般是用来保存W号的地址信息。这里的W号一般是指函数名及变量(局部、全局Q。根据这个地址信息Q便可以把地址译成相应的W号Q很多系l工兗debugҎ都要用到q种信息?/p>
Q一Q一个程序编译完以后内容会分成两大类保存Q一cLcodeQ一cLdataQ?/p>
Q?Qcode指程序代码,常存?text section
Q?Qdata指存E序中声明的变量Q常存在.data sectionQ未初始化的变量会被存在.bss section?/p>
Q二QWindows
Q?Q单个模块的map文g
在Windows下每一个模块(dll/exeQ对应一个map文gQ只需~译时打开相应的选项卛_?/p>
visual studio中方法:叛_工程Q选择PropertiesQ然后选择 Configuration Properties -Linker - DebuggingQ将Generate Map FileҎ成Yes?/p>
~译后在debug/release目录里便可以扑ֈ与应用程序同名的map文g?/p>
如下为map文g内容Q?/p>
Timestamp is4b9603e2 (Tue Mar 09 16:16:34 2010) //q个是时间戳Q每ơ编译都不同Q后面符号对应的地址一般也不同?/p>
Preferred loadaddress is 00010000 //q是~译时的预装载地址Q实际上模块被加载的地址可能跟这个不同,所以来定某个地址对应哪个W号信息的时候,q需要知道该模块加蝲在内存的真正起始地址Q然后根据偏U量来确定?/p>
Start Length Name Class
0001:00000000
0003:000008b8000af67cH .data DATA ==》初始化的变?/p>
0003:000aff40003930b1H .bss DATA ==》未初始化的变量
Q?Q操作系lȝmap文gQ不知道有没有?/p>
Q?Qdumpbin
dumpbin是一个反汇编工具Q可以输出exe/dll文g的许多信息?/p>
dumpbin /allyourmodulename > a.txt 可以把所有的信息保存在一个a.txt中,里面可以扑ֈ旉戟뀁原debug路径信息及函数列表等?/p>
如下Q?/p>
FILE HEADERVALUES
6 number of sections
49EC0BAE time date stamp Mon Apr 2013:44:14 2009 //旉?/p>
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
OPTIONAL HEADERVALUES
10B magic # (PE32)
9.00 linker version
53E00 size of code
0 size of uninitialized data
1000 base of code
55000 base of data
10000000 image base (10000000 to100CDFFF)
1000 section alignment
200 file alignment
5.01 operating system version
0.00 image version
5.01 subsystem version
0 Win32 version
CE000 size of image
400 size of headers
其中 10000000 image base (10000000 to 100CDFFF)是重要的信息Q与map file中的 Preferred load address is10000000 意义相同?/p>
DebugDirectories
Time Type Size RVA Pointer
-------- ------ -------- -------- --------
49EC0BAE cv 81 000020FC CFC Format: RSDS, {A
Begin End Prolog Excpt 32bit Fixup 【Function Name?/p>
0000000010001000 10001040 10001010 N Y Y DllMain
0000000810001040 10001064 10001050 N Y Y ?InitApplet@@YAHPAUHWND__@@@Z (int __cdecl InitApplet(struct HWND__*))
0000001010001064 10001068 10001064 N Y Y ?TermApplet@@YAXXZ (void __cdecl TermApplet(void))
0000001810001068 100013DC 10001078 N Y Y CPlApplet
00000020
00000028100014B4 100014BC 100014B4 N Y Y GetCurrentProcess
00000030100014BC
00000038
00000040
0000004810001660 10001678 10001664 N Y Y exit
0000005010001678 10001690
0000005810001690
00000060
begin栏对应的地址与map里的地址是一致的Q非常类gmap文g?/p>
【注意:很多exe或dll在编译时时将此信息隐藏的QFunction Name会变成空的?/p>
Q三QLinux
Q?Q单个模块的map文g
暂还不清楚,大家知道的请告知?/p>
Q?Q操作系lȝmap文g
linuxpȝ~译Image后会生成一个system.mapQ里面存了被~译q内核的W号信息Q不同次的编译生成的system.map会有差异?/p>
因ؓ是操作系l的W号信息Q装载的地址都是固定的,所以不像windows单个模块那样靠偏U量定位Q直接通过地址可以直接找到对应的W号?/p>
其内容的重要的几个符号如下:
_stext//代码D开?/p>
_etext//代码D늻?/p>
__data_start//初始化的数据开?/p>
_edata//初始化的数据l束
__bss_start//未初始化数据开?/p>
_end//全部l束
Linux相对windows有个很重要的不同是,linux启动后在proc\kallsyms里也有一份类似Map文g的信息,cat命o可看到其内容Q有了这个就可以得到M一个内核的W号Q变量及函数名)的地址信息Q而不需要在~译完内核后Ҏ保存map文gQ这真是一个巨大的宝藏?/p>
而且Qproc\kallsym的信息比system.map多,在最后会有module部分的符号信息,q些信息会随着pȝ的变化而变化?/p>
Q?Qnm命o
nm命o用来昄某个可执行文件的W号信息。符号信息中会包含全局变量Q比如下面的xyzQ和函数名(比如下面的mainQ,q有一些编译器插入的符P比如下面的__data_start,__bss_startQ?/p>
W二列表C符L属性,其中大写代表globalQ小写代表local
Usage: nm[option(s)] [file(s)]
List symbols in[file(s)] (a.out by default).
CZQ?/p>
nm helo
08049ff4 d_GLOBAL_OFFSET_TABLE_
080484ec R_IO_stdin_used
w _Jv_RegisterClasses
08048500 r__FRAME_END__
08048340 t__do_global_dtors_aux
w __gmon_start__
08048430 T__libc_csu_fini
08048440 T__libc_csu_init
U __libc_start_main@@GLIBC_2.0
080484cc T _fini
080484e8 R_fp_hw
08048298 T _init
08048310 T_start
U printf@@GLIBC_2.0
helo.c如下Q?/p>
#include<stdio.h>
int x = 10;
int y = 20;
int z = 30;
extern int__data_start;//q里引用了编译器插入的符?/p>
int main(void)
{
int *ds = &__data_start;
printf("%p\n", ds);
printf("now x = %d\n", x);
ds+=3;
*ds = 100;
printf("now x = %d\n", x);
}
7Q?nbsp;IDB文g
The compiler savesstate information from the first compile in the project’s .IDB file (the default name is project.IDB or VC60.IDBfor files compiled without a project).
The compiler usesthis state information to speed subsequent compiles.
8Q?nbsp;SLN文g
Visual Studio.Solution 通过为环境提供对目、项目项和解x案项在磁盘上位置的引用,可将它们l织到解x案中?nbsp; 比如是生成Debug模式,q是Release模式,是通用CPUq是专用的等
9Q?nbsp;SUO文g
解决Ҏ用户选项 记录所有将与解x案徏立关联的选项Q以便在每次打开Ӟ它都包含您所做的自定义设|。比如你的VS布局,你的目最后编译的而又没有x的文?下次打开时用)
10Q?nbsp;