编辑:接受的答案下方的评论表明它可能是Android动态加载程序的问题.
我有一个带有静态成员的模板类的标题.在运行时,静态成员的地址在库和客户端代码中使用.模板在库和客户端代码中都是隐式实例化的.它在Linux和OSX上工作正常,符号是重复的,但标记为"unqued",如nm所示(见下文).但是,当我为ARM(Android)编译时,符号在DSO和可执行文件中都标记为弱.加载器不统一,符号在运行时有效复制!
我读了这些: 静态成员的两个实例,怎么可能呢? 静态模板数据成员存储 ,尤其是这个答案:https: //stackoverflow.com/a/2505528/2077394 和:http: //gcc.gnu.org/wiki/Visibility
但我仍然有点困惑.我知道可见性的属性有助于优化,但我认为它应该默认工作.我知道C++标准并不关心共享库,但这是否意味着使用共享库会破坏标准?(或者至少这个实现不符合C++标准?)奖励:我该如何修复它?(而不是使用模板不是一个可接受的答案:))
标题:
template<class T>
struct TemplatedClassWithStatic {
static int value;
};
template<class T>
int TemplatedClassWithStatic<T>::value = 0;
Run Code Online (Sandbox Code Playgroud)
shared.cpp:
#include "TemplateWithStatic.hpp"
int *addressFromShared() {
return &TemplatedClassWithStatic<int>::value;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中:
#include "TemplateWithStatic.hpp"
#include <cstdio>
int *addressFromShared();
int main() {
printf("%p %p\n", addressFromShared(), &TemplatedClassWithStatic<int>::value);
}
Run Code Online (Sandbox Code Playgroud)
并建立,看看符号定义:
生产.so:
g++-4.8 -shared src/shared.cpp -o libshared.so -I include/ -fPIC
Run Code Online (Sandbox Code Playgroud)
编译和链接主要:
g++-4.8 src/main.cpp -I include/ -lshared -L.
Run Code Online (Sandbox Code Playgroud)
符号标记为"唯一":
nm -C -A *.so a.out | grep 'TemplatedClassWithStatic<int>::value' …Run Code Online (Sandbox Code Playgroud)