g++ vtable error eclips kompiliert problemlos woran kanns leigen?



  • Hallo Liebe Kommunity,
    ich habe erneut ein Problem bei dem ich jetzt auch nach einiger zeit googlen
    zu keiner Lösung gekommen bin.
    Zum Problem: ich habe unter Linux mittels Eclipse ein Programm geschreiben.
    Dieses funktionier auch einwandfrei unter eclipse. Keine Fehlermendungen oder Warnungen. (habe extra in den optionen auf pedantic etc. gestellt).
    Wenn ich das programm nun aber auf Meinen Raspberri Pi Kopiere (die Quelldateien .cpp und .h) und es dann mit dem befehl "g++ -o programm -O0 -Wall
    xxx.cpp xxx.h usw. Kompilieren will bekomme ich immer folgende Fehlermeldungen:

    root@raspberrypi:/home/pi/watchDog/src# g++ -o watchdog -O0 -Wall  boxConfig.cpp boxConfig.h cfgRead.cpp cfgRead.h devConfig.cpp devConfig.cpp socketx.cpp socketx.h watchDog.cpp watchDog.h calcValue.cpp calcValue.h dataWrite.cpp dataWrite.h timerIntervall.cpp timerIntervall.h devRead.cpp devRead.h/tmp/ccMYJWtf.o: In function `devConfig::devConfig()':
    devConfig.cpp:(.text+0x0): multiple definition of `devConfig::devConfig()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x0): first defined here
    /tmp/ccMYJWtf.o:(.rodata+0x0): multiple definition of `vtable for devConfig'
    /tmp/ccNjoHp7.o:(.rodata+0x0): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::getAdresse()':
    devConfig.cpp:(.text+0xac): multiple definition of `devConfig::getAdresse()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0xac): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::getID()':
    devConfig.cpp:(.text+0xe0): multiple definition of `devConfig::getID()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0xe0): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::getValueInterpret()':
    devConfig.cpp:(.text+0x114): multiple definition of `devConfig::getValueInterpret()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x114): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::getRegNo()':
    devConfig.cpp:(.text+0x148): multiple definition of `devConfig::getRegNo()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x148): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::getStartReg()':
    devConfig.cpp:(.text+0x170): multiple definition of `devConfig::getStartReg()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x170): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::setRegNo(long)':
    devConfig.cpp:(.text+0x198): multiple definition of `devConfig::setRegNo(long)'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x198): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::setStartReg(long)':
    devConfig.cpp:(.text+0x1c4): multiple definition of `devConfig::setStartReg(long)'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x1c4): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::setAdresse(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
    devConfig.cpp:(.text+0x1f0): multiple definition of `devConfig::setAdresse(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x1f0): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::setID(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
    devConfig.cpp:(.text+0x220): multiple definition of `devConfig::setID(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x220): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::setvalueInterpret(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
    devConfig.cpp:(.text+0x250): multiple definition of `devConfig::setvalueInterpret(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x250): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::~devConfig()':
    devConfig.cpp:(.text+0x280): multiple definition of `devConfig::~devConfig()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x280): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::~devConfig()':
    devConfig.cpp:(.text+0x348): multiple definition of `devConfig::~devConfig()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x348): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::~devConfig()':
    devConfig.cpp:(.text+0x280): multiple definition of `devConfig::~devConfig()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x280): first defined here
    /tmp/ccMYJWtf.o:(.rodata+0x10): multiple definition of `typeinfo for devConfig'
    /tmp/ccNjoHp7.o:(.rodata+0x10): first defined here
    /tmp/ccMYJWtf.o:(.rodata+0x28): multiple definition of `typeinfo name for devConfig'
    /tmp/ccNjoHp7.o:(.rodata+0x28): first defined here
    /tmp/ccMYJWtf.o: In function `devConfig::devConfig()':
    devConfig.cpp:(.text+0x0): multiple definition of `devConfig::devConfig()'
    /tmp/ccNjoHp7.o:devConfig.cpp:(.text+0x0): first defined here
    collect2: ld returned 1 exit status
    

    Die zugehörige Klasse siet wie folgt aus:
    devConfig.h

    #ifndef DEVCONFIG_H_
    #define DEVCONFIG_H_
    
    #ifndef TIMERINTERVALL_H_
    #include "timerIntervall.h"
    #endif
    
    #include <string>
    
    using namespace std;
    
    class devConfig : public timerIntervall {
    public:
    	devConfig();
    	devConfig(const devConfig& dConfig);
    	virtual ~devConfig();
    
    	int getRegNo();
    	int getStartReg();
    	string getAdresse();
    	string getID();
    	string getValueInterpret();
    
    	void setRegNo(long int);
    	void setStartReg(long int);
    	void setAdresse(string);
    	void setID(string);
    	void setvalueInterpret(string);
    
    private:
    	int regNo;		//anzahl der register die gelesen weden sollen z.B. 1 Integer 2 float
    	int startReg;	//start register des Sensors
    
    	string adresse;		//ip adresse des sensors
    	string id;			//eindeutige id des senors
    	string valueInterpret;	// umrechnungs wert der messwerte
    };
    
    #endif /* DEVCONFIG_H_ */
    

    Ich werde die zugehörige cpp nicht posten da es sich wie die Funktionsnamen bereits sagen nur um getter und setter Funktionen handelt.

    Die Header datei zu der vererbten klasse:
    Timerintervall.h

    #ifndef TIMERINTERVALL_H_
    #define TIMERINTERVALL_H_
    #ifndef TIME_H_
    #include <time.h>
    #endif
    
    using namespace std;
    
    class timerIntervall {
    public:
    	timerIntervall();
    	timerIntervall(const timerIntervall& tVal);
    	~timerIntervall(); //destruktor
    	int setIntervall(int intervall);
    	int getIntervall();
    	int Start();
    	int getTimerInt();
    
    private:
    
    	int intervall;			// in minuten
    	time_t Takt;			// aktuelle zeit des durchlaufes
    	time_t T0;				//erstellungszeit des letzten logfiles
    };
    
    #endif /* TIMERINTERVALL_H_ */
    

    Die entsprechenden objekte werden in der main erstellt:

    #include <iostream>
    
    #ifndef WATCHDOG_H_
    #include "watchDog.h"
    #endif
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    .
    .
    .
    
    /***OBJEKTE*********************************************************/
    	cfgRead config;
    	boxConfig bconf;   // das boxConfig Objekt
    	devConfig *dconf;  // Pointer auf ein Array von devConfig Objekten
    /***OBJEKTE*********************************************************/
    
    /***CONFIGURATION***************************************************/
    	config.ReadBoxConfig(bconf);
    
    	if (argc<=1){  //wenn ohne parameter gestartet wird nicht ausführen
    //Eingaben prüfen Box zugriff auf bconf....
    	}
    
    	devRead dread(bconf.getDevAnz()); 			// in devRead das Feld mit den sockets anlegen
    	dconf = new devConfig[bconf.getDevAnz()];   // Feld f�r die devConfig Objekte erstellen (Speichert Informationen der Sensoren )
    
    	for(int i=0; i<bconf.getDevAnz(); i++)
    	{
    //eingaben prüfen device
    		}
    		try{
    			dread.init(dconf[i].getAdresse(),i); //socket anlagen und verbinden
    		}catch(SockExcept& s){
    		//TODO hier fehler posten
    			int error = 0;
    			string err;
    			err = s.get_SockExcept(error);
    			cout<<"error ::"<< error <<"::" << err << endl;
    		}
    	} //Config stimmt
    
    /***CONFIGURATION***************************************************/
    
    .
    . hier wird nurnoch lesend auf dconf zugegriffen
    .
    .
    .
    
    	/*AUFRÄUMEN*/
    
    	delete [] dconf;
    	return(0);
    	//exit(EXIT_SUCCESS);
    }
    

    nun ich habe gelesen, das solche vtable Problem entstehen können, wenn die Vtable einer Klasse in einem anderem file abgelegt wird. Da ich jedoch nicht
    weiß wie ich dies rausfinden geschweige denn beheben könnte frage ich jetzt mal
    hier nach. bis jetzt habt ihr mir ja auch immer ein Brett vor den Kopf genagelt 😃
    danke schon mal im Voraus.

    MFG BabCom



  • Ich würde erst einmal alle Dateien einzeln compilieren und linken. Dann kann man die betroffenen Objektdateien auch einfach identifizieren. Aus den Namen der temporären Objektdateien kann man hier ja nicht erkennen, welche ÜEs das betrifft.



  • Könnte das Problem sein, dass du die .h-Dateien an den Compiler übergibst?



  • Bashar schrieb:

    Könnte das Problem sein, dass du die .h-Dateien an den Compiler übergibst?

    Das wird wahrscheinlich Mitursache sein. Wenn sich dazu noch nicht-inline Funktionsdefinitionen im Header befinden, wäre das beschriebene Verhalten zu erwarten.



  • Sollte ich dan mal versuche die Hederdateien als libaries einzubinden? (g++ parameter -I/usr/include/xxx)



  • Nein, du sollst sie gar nicht übergeben. Headerfiles werden durch #include eingebunden. Und das scheint ja zu funktionieren, sonst hätte sich dein Präprozessor schon beschwert, nicht erst der Linker.

    Übrigens fügt -I keine Library hinzu, sondern einen Suchpfad für Headerfiles. Und das brauchst du hier, wie gesagt, nicht.



  • Hey danke für die schnelle hilfe. Ich habe die headers jetzt einfach in ein extra Verzeichnis kopiert und mittels -I/.../headers dem kompiler bekannt gemacht und es hatt geklappt.(sogar deutlich schneller als er sonst benötigt hatt um das gesamte Projekt zu kompilieren)
    THX


Anmelden zum Antworten