程序链接静态lib时,会将使用到的code部分包含进最终的exe或dll中,如果lib中定义了全局变量,但这个全局变量并没有被其他code使用到,那么最终的exe/dll会执行这个全局变量的定义语句吗?
[Windows 平台] VS2008
创建TestLib工程,configuration type选择static library(lib)。创建一个简单的类People。
TestLib.h
#include<string>
class People
{
public:
People(std::string name);
~People();
std::string _name;
};
TestLib.cpp
构造函数打印语句。定义了一个全局变量g_Person。
#include "stdafx.h"
#include <iostream>
#include "TestLib.h"
People::People(std::string name)
{
std::cout << "Create a new People instance: " << name << std::endl;
_name = name;
}
People::~People()
{
}
People g_Person("Lily");
再创建一个C++ console工程TestLibConsole。链接TestLib(solution property的project dependencies中设置)。
#include <iostream>
#include "../TestLib/TestLib.h"
using namespace std;
int main()
{
cout << "Begin TestLibConsole.exe" << endl;
int local = 1;
//People p("Panda");
cout << "End TestLibConsole.exe" << endl;
return 0;
}
1. 想像中,在load的时候,main函数执行之前,应该初始化g_Person,有输出“Create a new People instance:Lily”,但是没有:(
编译器没有发现对TestLib.lib有任何方式的引用,所以根本没有把相关code包含进最终的TestLibConsole.exe中。
2种方法确认:
1) Notepad++ 打开TestLibConsole.pdb文件,搜索“People”,找不到这个symbol。
2) 用windbg debug,Open Executable... 打开TestLibConsole.exe。
lm (列出加载的模块)
ld * (Load symbols)
lm(这时应该会列出TestLibConsole.pdb了)
x TestLibConsole!*Local* (有输出,命令x是检查symbol)
x TestLibConsole!*People* (没有输出)
(其他windog命令:dv, dt, k)
2. 将“People p("Panda")” 的注释去掉,编译执行,如期输出
Create a new People instance:Lily
Begin TestLibConsole.exe
Create a new People instance:Panda
End TestLibConsole.exe
3. 可是有时候并不想在exe中这么调用lib中的code,可以这么做:
在TestLib.h 增加:
int ForceLinkMethod();
const int ForceLinkVar = ForceLinkMethod();
在TestLib.cpp中增加:
int ForceLinkMethod()
{
return 0;
}
这样即使没有“People p("Panda")”,这个语句,也会正确初始化全局变量g_Person。
[Linux平台] Fedora14
经过测试,Linux的gcc/g++编译器的处理方法和Windows VS一样。
TestLib.h TestLib.cpp TestLibConsole.cpp 都在同一个目录下。
>g++ -c TestLib.cpp
编译出目标文件:TestLib.o
>ar rcs libTestLib.a TestLib.o
生成静态lib。命名规则以“lib”为前缀。
>g++ TestLibConsole.cpp libTestLib.a -o TestLibConsole
编译TestLibConsole.cpp,链接TestLib.a,生成可执行文件TestLibConsole。
>./TestLibConsole
执行。
在Linux上debug可以使用Eclipse和gdb,下篇介绍。
[参考]
http://hi.baidu.com/gaomanyi/blog/item/1be9a11bdca98c1f8718bf9e.html
http://www.cnblogs.com/InterMa/archive/2006/07/03/441801.html
http://bbs.byr.cn/pc/pccon.php?id=2717&nid=78218