2010-04-30 4 views
3

Я строю двумерный игровой движок с открытым исходным кодом под названием YoghurtGum. Сейчас я работаю над портом Android, используя NDK, предоставленный Google.GCC: Простой тест наследования терпит неудачу

Я схожу с ума из-за ошибок я получал в моем приложении, поэтому я сделал простую тестовую программу:

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; 
} 

кажется достаточно просто, правда? Вот как я скомпилировать, который так же, как я скомпилировать остальную часть моего кода:

/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 

(Разрывы строк добавлены для ясности). Это прекрасно компилируется. Но тогда мы получаем линкер:

/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 

Как вы можете сказать, что есть много хлама там, что на самом деле не нужно. Это потому, что это не работает. Он не работает со следующими ошибками:

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 

Это те же ошибки, которые я получаю от своего фактического приложения.

Если кто-то может объяснить мне, где я ошибся в своем тесте или какой вариант, или я забыл в своем компоновщике, я был бы очень, очень благодарен.

Заранее спасибо.

UPDATE:

Когда я делаю мои деструкторов, не встраиваются, я получаю новые и более интересные ошибки ссылка:

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

Будет ли это работать, если вы добавите -fPIC? – ognian

+0

Я боюсь, что это связано с C++, а это значит, что вы много страдаете. Для начала используйте 'C++ filt', чтобы узнать, каково его человеко-читаемое имя. Также я не думаю, что libgcc_s.so имеет какое-либо отношение к C++ –

ответ

9

Использование г ++ управлять линкер, не НКУ:

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

Обновление: возникает другая проблема, связанная с использованием вами -nostdlib. Это останавливает компилятор от добавления всех стандартных библиотек (таких как библиотека времени выполнения, которая предоставляет ваши недостающие внешние ресурсы). Есть ли причина, в которой вы нуждаетесь?

+0

Не работает. Те же ошибки. – knight666

+0

@ knight666 - заметил еще одну проблему и обновленный ответ. –

+0

К сожалению, это также не решает проблему. Это также может быть связано с тем, что Android не предоставляет реализацию стандартной библиотеки шаблонов. – knight666

1

Вы пытались создать в своем списке инициализации базу, на которой вы не наследовали. Автомобиль наследует только Автомобиль, а не Базу. Из вашего кода я предполагаю, что это было вашим намерением.

Я лично предпочитаю использовать композицию, а не множественное наследование - это более чистая и лучшая производительность.

+0

Это очень «C с классами» вместо «C++». По моему скромному мнению, конечно. Композиция в основном абстрагирует реализацию, не так ли? Кроме этого, мне действительно нужно наследование. Мне нужен класс Object, который является прародителем всего, классом Entity, который является производным от Object и внутриигрового объекта, и такими вещами, как Player, Bullet, Alien и т. Д., Который является производным от Entity. – knight666

+1

Нет. Вы используете наследование, когда хотите виртуальные функции. Если вам не нужны виртуальные функции, не используйте наследование. Композиция намного чище, чем обычное наследование, и вы получаете гораздо больший контроль, а также решаете проблемы с МИ. Наследование - это не решение всех решений, и есть определенные моменты, когда это неверно. Об этом говорит весь язык Java. Однако вы все еще не наследовали Car from Base и пытались создать экземпляр базового класса, из которого вы не наследовали. Я поражен, что даже компилируется. – Puppy

+0

Конечно, он компилируется. Он НАХОДИТ на основе Base, и это очень ясно. Так работает наследование. –

1

Попробуйте добавить -fno-rtti -fno-exceptions в г ++ командной строки

+0

В другом ответе объясняется, как установить ссылку на libstdC++. В этом ответе объясняется, как избежать зависимости libstdC++, которая (для меня) намного полезнее. – Alcaro