最近用过了 GPUImage 做美颜功能,为了防止冲突把里面的类名改了,但是有些全局的变量没有注意到,没有改名。我们做的是SDK静态库,结果我把库给出去后,第三方也用到了GPUImage,编译链接的时候并没有报冲突,但是程序跑起来的时候挂掉了。后来跟了一下,奔溃原因如下:
//下面的数组是个全局变量
// BT.709, which is the standard for HDTV.
const GLfloat kColorConversion709[] = {
1.164, 1.164, 1.164,
0.0, -0.213, 2.112,
1.793, -0.533, 0.0,
};
在另外一个文件中用extern引用
extern const GLfloat kColorConversion601[];
使用该值得地方,夹断点调试,正常 _preferredConversion 赋值后为 1,有问题的时候,从kColorConversion601 内存拿不到值,访问内存崩溃:
_preferredConversion = kColorConversion601;
问题:
- 上面说的全局变量,在SDK中一共有两份,没有编译链接错误,这是什么原因,能说下具体编译链接的过程吗?
- 猜想是有两份相同变量,去找变量的时候地址错误了,这个过程具体是怎样的,很想知道
- 如果调整下库的链接顺序,奔溃的问题可以解决,感觉挺奇怪的
希望了解到朋友给讲一下,虽然问题找到了,也解决了,但是很想知道为什么?### 问题描述
问题出现的环境背景及自己尝试过哪些方法
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
0、"为了防止冲突把里面的类名改了":可以直接使用GPUImage的头文件,而不链接GPUImage代码,这样产出的二进制体积会更小。
1、全局变量有两份,除非加了static,否则肯定报duplicate symbol
2、“猜想是有两份相同变量,去找变量的时候地址错误了”:应该是C++的类有两份,而不是全局变量有两份
3、“如果调整下库的链接顺序,奔溃的问题可以解决”:C++的编译规则,一个类有多份实现,取最先链接的那一份实现