2010-04-30 4 views
3

Je construis un moteur de jeu 2D open source appelé YoghurtGum. En ce moment je travaille sur le port d'Android, en utilisant le NDK fourni par Google.GCC: échec du test d'héritage simple

Je devenais fou à cause des erreurs que je recevais dans ma demande, donc je fait un programme de test simple:

class Base 
{ 

public: 

    Base() { } 
    virtual ~Base() { } 


}; // class Base 

class Vehicle : virtual public Base 
{ 

public: 

    Vehicle() : Base() { } 
    ~Vehicle() { } 


}; // class Vehicle 

class Car : public Vehicle 
{ 

public: 

    Car() : Base(), Vehicle() { } 
    ~Car() { } 

}; // class Car 

int main(int a_Data, char** argv) 
{ 
    Car* stupid = new Car(); 

    return 0; 
} 

semble assez facile, non? Voici comment je compile, ce qui est de la même façon que je compilez le reste de mon code:

/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-g++ 
-g 
-std=c99 
-Wall 
-Werror 
-O2 
-w 
-shared 
-fshort-enums 
-I ../../YoghurtGum/src/GLES 
-I ../../YoghurtGum/src 
-I /home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/include 
-c src/Inheritance.cpp 
-o intermediate/Inheritance.o 

(sauts de ligne sont ajoutés pour plus de clarté). Cela compile bien. Mais nous arrivons à l'éditeur de liens:

/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc 
-lstdc++ 
-Wl, 
--entry=main, 
-rpath-link=/system/lib, 
-rpath-link=/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib, 
-dynamic-linker=/system/bin/linker, 
-L/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0, 
-L/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib, 
-rpath=../../YoghurtGum/lib/GLES 
-nostdlib 
-lm 
-lc 
-lGLESv1_CM 
-z 
/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o 
/home/oem/android-ndk-r3/build/platforms/android-5/arch-arm/usr/lib/crtend_android.o 
intermediate/Inheritance.o 
../../YoghurtGum/bin/YoghurtGum.a 
-o bin/Galaxians.android 

Comme vous pouvez le constater, il y a beaucoup de cochonneries là-dedans qui est pas vraiment nécessaire. C'est parce que ça ne marche pas. Il échoue avec les erreurs suivantes:

intermediate/Inheritance.o:(.rodata._ZTI3Car[typeinfo for Car]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info' 
intermediate/Inheritance.o:(.rodata._ZTI7Vehicle[typeinfo for Vehicle]+0x0): undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info' 
intermediate/Inheritance.o:(.rodata._ZTI4Base[typeinfo for Base]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info' 
collect2: ld returned 1 exit status 
make: *** [bin/Galaxians.android] Fout 1 

Ce sont les mêmes erreurs que je reçois de mon application actuelle.

Si quelqu'un pouvait m'expliquer où je me suis trompé dans mon test ou quelle option ou j'ai oublié dans mon éditeur de liens, je serais très, extrêmement reconnaissant.

Merci d'avance.

MISE À JOUR:

Quand je fais mes Destructeurs non inline, je reçois de nouvelles erreurs de lien plus excitant:

intermediate/Inheritance.o:(.rodata+0x78): undefined reference to `vtable for __cxxabiv1::__si_class_type_info' 
intermediate/Inheritance.o:(.rodata+0x90): undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info' 
intermediate/Inheritance.o:(.rodata+0xb0): undefined reference to `vtable for __cxxabiv1::__class_type_info' 
collect2: ld returned 1 exit status 
make: *** [bin/Galaxians.android] Fout 1 
+0

Est-ce que ça marche si vous ajoutez -fPIC? – ognian

+0

Je crains que cela soit lié au C++, ce qui signifie que vous allez beaucoup souffrir. Pour commencer, utilisez 'C++ filt' pour savoir quel est son nom lisible par un humain. Aussi je ne pense pas que libgcc_s.so a quelque chose à voir avec C++ –

Répondre

9

Utilisez g ++ pour conduire l'éditeur de liens, non gcc:

/home/oem/android-ndk-r3/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-g++ 
-Wl, 
--entry=main, 
... 

Mise à jour: un autre problème semble être votre utilisation de -nostdlib Cela empêche le compilateur d'ajouter toutes les bibliothèques standard (telles que la bibliothèque d'exécution qui fournit vos externes manquants). Y a-t-il une raison pour laquelle vous en avez besoin?

+0

Ne fonctionne pas. Mêmes erreurs – knight666

+0

@ knight666 - a remarqué un autre problème et une mise à jour de la réponse. –

+0

Malheureusement, cela ne résout pas le problème. Cela peut également être dû au fait qu'Android ne fournit pas une implémentation de la bibliothèque de modèles standard. – knight666

1

Vous avez essayé d'instancier dans votre liste d'initialisation une base dont vous n'avez pas hérité. La voiture hérite seulement du véhicule et non de la base. De votre code je suppose que c'était votre intention.

Personnellement, je préfère utiliser la composition plutôt que l'héritage multiple - c'est plus propre et de meilleures performances.

+0

C'est très "C avec les classes" au lieu de "C++". À mon humble avis, bien sûr. La composition consiste essentiellement à abstraire la mise en œuvre, n'est-ce pas? A part ça, j'ai vraiment besoin d'héritage. J'ai besoin d'une classe Object qui est le grand-parent de tout, d'une classe Entity dérivée de Object et d'un objet dans le jeu et de choses comme Player, Bullet, Alien, etc., qui est dérivé de Entity. – knight666

+1

Non. Vous utilisez l'héritage lorsque vous voulez des fonctions virtuelles. Si vous ne voulez pas de fonctions virtuelles, n'utilisez pas l'héritage. La composition est beaucoup plus propre que l'héritage régulier et vous gagnez beaucoup plus de contrôle, ainsi que résout les problèmes avec MI. L'héritage n'est pas une solution globale, et il y a certainement des moments où ce n'est pas correct. Tout le langage Java le montre. Toutefois, vous n'avez toujours pas hérité de Car de Base et vous avez essayé d'instancier une classe de base dont vous n'avez pas hérité. Je suis étonné que même compile. – Puppy

+0

Bien sûr, il compile. Il hérite de Base, et c'est très clair. C'est comme ça que l'héritage fonctionne. –

1

Essayez d'ajouter -fno-rtti -fno-exceptions à g ++ ligne de commande

+0

L'autre réponse explique comment lier à libstdC++. Cette réponse explique comment éviter la dépendance de libstdC++, qui (pour moi) est beaucoup plus utile. – Alcaro

Questions connexes