前段时间被别人问到这个问题,当时没想到答案,事后自己研究了一下,结果还挺有趣的,特地记录一下。测试源代码如下
so库头文件
#ifndef SOTEST_H
#define SOTEST_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <stdlib.h>
void getnum();
void setnum(int Num);
#ifdef __cplusplus
}
#endif
#endif /* SOTEST_H */
so库源文件
#include "test.h"
int num=0;
void getnum()
{
printf("num=%d\n",num);
}
void setnum(int Num)
{
num=Num;
}
测试代码
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
int num;
/*
*
*/
int main(int argc, char** argv)
{
num=10;
getnum();
setnum(20);
getnum();
printf("num=%d\n",num);
return (EXIT_SUCCESS);
}
首先对so库进行正常编译,输出结果为
num=10
num=20
num=20
然后重新对so库进行编译,此时加上选项
-Wl,-Bsymbolic
这次的运行结果为
num=0
num=20
num=10
发现两次运行结果不一样,原来是因为应用程序进行链接的时候,动态库中的全局变量定义,将会被应用程序中同名的全局变量所覆盖。这样也就造成了,无论是在动态库中或者应用程序中修改全局变量,其值都会发生变化。
想要是动态库中的全局变量不被影响,就需要添加额外的选项,Wl表示将紧跟其后的参数,传递给连接器ld。Bsymbolic表示强制采用本地的全局变量定义,这样就不会出现动态链接库的全局变量定义被应用程序的同名定义给覆盖了!