gpt4 book ai didi

c++ - 跨动态库的静态*模板*类成员

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:29:31 25 4
gpt4 key购买 nike

编辑:已接受答案下方的评论表明这可能是 Android 动态加载器的问题。

我有一个带有静态成员的模板类的 header 。在运行时,静态成员的地址在库和客户端代码中使用。该模板在库和客户端代码中都被隐式实例化。它在 Linux 和 OSX 上运行良好,符号重复但标记为“唯一”,如 nm 所示(见下文)。但是,当我为 ARM (Android) 编译时,该符号在 DSO 和可执行文件中都被标记为 weak。加载程序不统一,符号在运行时有效复制!

我读了这些: two instances of a static member, how could that be? Static template data members storage尤其是这个答案: 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;

共享.cpp:

#include "TemplateWithStatic.hpp"
int *addressFromShared() {
return &TemplatedClassWithStatic<int>::value;
}

主要.cpp:

#include "TemplateWithStatic.hpp"
#include <cstdio>

int *addressFromShared();
int main() {
printf("%p %p\n", addressFromShared(), &TemplatedClassWithStatic<int>::value);
}

然后构建,查看符号定义:

生成.so:

 g++-4.8  -shared src/shared.cpp  -o libshared.so -I include/ -fPIC

编译链接main:

 g++-4.8 src/main.cpp -I include/ -lshared -L.

符号被标记为“唯一”:

nm -C -A *.so a.out | grep 'TemplatedClassWithStatic<int>::value'
libshared.so:0000000000200a70 u TemplatedClassWithStatic<int>::value
a.out:00000000006012b0 u TemplatedClassWithStatic<int>::value

生产.so

~/project/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-g++    -o libshared.so src/shared.cpp   -I include/  --sysroot=/Users/amini/project/android-ndk-r9/platforms/android-14/arch-arm/ -shared

编译链接主体

~/project/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-g++  src/main.cpp  libshared.so    -I include/  --sysroot=${HOME}/project/android-ndk-r9/platforms/android-14/arch-arm/  -I ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/include -I ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/include/backward    -I ~/project/android-ndk-r9/platforms/android-14/arch-arm/usr/include  ~/project/android-ndk-r9/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/libgnustl_static.a -lgcc

符号很弱!

nm -C -A *.so a.out | grep 'TemplatedClassWithStatic<int>::value'
libshared.so:00002004 V TemplatedClassWithStatic<int>::value
a.out:00068000 V TemplatedClassWithStatic<int>::value

编辑,注意上下文:我正在玩 OOLua,一个帮助将 C++ 绑定(bind)到 Lua 的库,当我开始以 Android 为目标时,我的单元测试失败了。我不“拥有”代码,我宁愿对其进行深入修改。

编辑,在 Android 上运行它:

adb push libshared.so data/local/tmp/
adb push a.out data/local/tmp/
adb shell "cd data/local/tmp/ ; LD_LIBRARY_PATH=./ ./a.out"
0xb6fd7004 0xb004

最佳答案

Android 不支持唯一符号。它是 ELF 格式的 GNU 扩展,仅适用于 GLIBC 2.11 及更高版本。 Android 根本不使用 GLIBC,它使用了一个名为 Bionic 的不同 C 运行时。

(更新) 如果弱符号对您不起作用(结束更新) 恐怕您将不得不修改代码,使其不依赖关于静态数据。

关于c++ - 跨动态库的静态*模板*类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23261702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com