Bearbeiten: die Kommentare unter der angenommenen Antwort zeigen, dass es ein Problem mit dem Android Dynamic Loader sein könnte.Statische * Vorlage * Klassenmitglied über dynamische Bibliothek
Ich habe eine Überschrift für eine Vorlagenklasse mit einem statischen Mitglied. Zur Laufzeit wird die Adresse des statischen Members in der Bibliothek und im Client-Code verwendet. Die Vorlage wird implizit sowohl in der Bibliothek als auch im Client-Code instanziiert. Es funktioniert gut unter Linux und OSX, das Symbol ist dupliziert, aber markiert als "uniqued", wie durch nm angezeigt (siehe unten). Allerdings, wenn ich für ARM (Android) kompilieren, wird das Symbol sowohl im DSO als auch in der ausführbaren Datei als schwach markiert. Der Loader vereinheitlicht nicht und das Symbol wird zur Laufzeit effektiv dupliziert!
Ich lese diese: two instances of a static member, how could that be? Static template data members storage und vor allem diese Antwort: https://stackoverflow.com/a/2505528/2077394 und: http://gcc.gnu.org/wiki/Visibility
aber ich bin immer noch ein wenig verwirrt. Ich verstehe, dass die Attribute für die Sichtbarkeit zu optimieren helfen, aber ich dachte, es sollte standardmäßig funktionieren. Ich weiß, dass der C++ - Standard sich nicht um eine gemeinsam genutzte Bibliothek kümmert, aber bedeutet dies, dass die Verwendung von gemeinsam genutzten Bibliotheken den Standard bricht? (oder zumindest diese Implementierung ist nicht C++ Standard konform?) Bonus: Wie kann ich es beheben? (Und nicht die Vorlage ist keine akzeptable Antwort :))
Rubrik:
template<class T>
struct TemplatedClassWithStatic {
static int value;
};
template<class T>
int TemplatedClassWithStatic<T>::value = 0;
shared.cpp:
#include "TemplateWithStatic.hpp"
int *addressFromShared() {
return &TemplatedClassWithStatic<int>::value;
}
main.cpp:
#include "TemplateWithStatic.hpp"
#include <cstdio>
int *addressFromShared();
int main() {
printf("%p %p\n", addressFromShared(), &TemplatedClassWithStatic<int>::value);
}
und Gebäude , Blick auf die Symbole Definitionen:
Herstellung .so:
g++-4.8 -shared src/shared.cpp -o libshared.so -I include/ -fPIC
Kompilieren und Linken Haupt:
nm -C -A *.so a.out | grep 'TemplatedClassWithStatic<int>::value'
libshared.so:0000000000200a70 u TemplatedClassWithStatic<int>::value
a.out:00000000006012b0 u TemplatedClassWithStatic<int>::value
Herstellung .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
:
g++-4.8 src/main.cpp -I include/ -lshared -L.
Symbole als "einzigartig" gekennzeichnet sind, Kompilieren und Verknüpfen Haupt
~/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
Symbole sind schwach!
nm -C -A *.so a.out | grep 'TemplatedClassWithStatic<int>::value'
libshared.so:00002004 V TemplatedClassWithStatic<int>::value
a.out:00068000 V TemplatedClassWithStatic<int>::value
bearbeiten, Note für den Kontext: Ich mit OOLua spielt, eine Bibliothek zu helfen Bindung C++ zu Lua und meine Unittests noch nicht bestehen, als ich begann Android Ziel. Ich "besitze" den Code nicht und würde ihn lieber tief modifizieren.
bearbeiten, es auf Android laufen:
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
Danke. Sollte ich zu dem Schluss kommen, dass die Android-Toolchain den vollständigen C++ - Standard nicht unterstützt, solange Sie Shared Libraries verwenden? – Joky
"Die Android-Toolchain unterstützt den C++ - Standard nicht vollständig, solange Sie Shared Libraries verwenden" - Eigene Experimente mit schwachen Symbolen (unter Linux) deuten darauf hin, dass sie tatsächlich für statische Daten in gemeinsam genutzten Bibliotheken funktionieren. Das heißt, der Linker wird nur eines der schwachen Symbole verwenden, die anderen werden ignoriert. Hast du versucht, dein Programm zu starten? –
Ja, die gedruckte Adresse ist anders (nur für Android) – Joky