Komischer Linker Fehler mit CBuilder 6 Personal Edition



  • Folgendes Problem:

    class1.h

    class class1
    {
      int func1(args);
      int func2(args);
    }
    

    class1.cpp

    int class1::func1(args)
    {
      ...
      return true;
    }
    int class1::func2(args)
    {
      ...
      return true;
    }
    

    programm

    #include "class1.h"
    class1 inst;
    ...
      inst.func1(...);
      inst.func2(...);
    

    So, wo soll nun das Problem liegen? Das liegt dort, das der linker func2 nicht auflösen kann. func2 ist auch nicht im map-file zu finden.
    Dazu ist noch zu sagen, das func2 zu func1 absolut identisch ist, bis auf den Namen. Und func2 wurde erst eine Weile später hinzugefügt.
    Innerhalb der Klasse kann ich ohne Probleme auf mit beiden Funktionen arbeiten.

    Hat die Personal Edition eventuell irgendeine interne Begrenzung der exportierten Funktionen?



  • in der class1.cpp-Datei fehlt #include "class1.h".
    Obwohl... dann sollte der Compiler meckern. Wie sieht es es eigentlich mit Parametern der Funktion aus? Vielleicht sind sie unterschiedlich. Oder ist da irgendwo ein const/inline bei, wo keiner sollte?



  • Hast du auch "public:" vor func2 in der Klassendefinition?



  • Beide Funktionen sind public und auch das include fehlt nicht, hab ich nur vergessen mit hinzuschreiben.
    Die funktionen sind auch vollkommen identisch, bis auf den Namen halt. Das sie identisch sind ist aber eh nur ein test, weil ich eigentlich eine andere Funktion hinzufügen wollte, wo ich halt den Fehler bekam das der Linker sie nicht finden kann. Um irgendwelche möglichen Schreibfehler auszuschliessen, hab ich halt auch einfach mal eine bereit funktionierende Funktion kopiert.
    Ich versteh das nicht. In anderen Klassen kann ich neue Funktionen anlegen, nur in der einen ist irgend etwas faul.
    Hier mal die eigentliche Klasse, leicht gekürzt. Hoffe das ist nicht zu groß hier.

    //---------------------------------------------------------------------------
    
    #ifndef DataBaseH
    #define DataBaseH
    //---------------------------------------------------------------------------
    #include "xml.h"
    
    struct SItem
    {
    	AnsiString	strName;
       ...
    };
    
    struct SIItem
    {
    	SItem	Item;
    	bool bChanged;
    };
    
    class CMDataBase
    {
    public:
    	CMDataBase();	// Konstruktor
    	~CMDataBase();	// und Destruktor
    
    	int Init(void);	// Initialisieren und laden der DB
    	int OpenXml2(AnsiString sFileName);	// Lade eine angegebene Xml-Datei
    	int OpenXml(AnsiString sFileName);	// Lade eine angegebene Xml-Datei
    	int AddItem(SItem *Item);
    
    private:
    	CXml	xFile;	// Das xml-Ojekt
    	AnsiString	sFileNameDrops;	// Dateiname der Datei mit den Dropgegenständen
    	AnsiString	sFileNameOthers;	// Dateiname für die anderen Gegenstände
    
    	DynamicArray<SIItem>	arItems;
    	int nItems;	// Anzahl der Items in der DB
    };
    
    #endif
    

    und die Implementation

    //---------------------------------------------------------------------------
    // Dieses Modul enthält alle Itemdaten, getrennt nach Drop und Unique/Crafted
    #include <assert.h>
    
    #pragma hdrstop
    
    #include "DataBase.h"
    
    //---------------------------------------------------------------------------
    
    CMDataBase::CMDataBase()
    {	// Dateinamen sind schonmal voreingestellt
    	sFileNameDrops = "Items.xml";
    	sFileNameOthers = "Items_private.xml";
    	nItems = 0;
    }
    
    // Destruktor
    CMDataBase::~CMDataBase()
    {
    }
    
    // Initialisieren und laden der Datenbank
    // Einen richtigen Fehlschlag gibts noch nicht, deshalb immer 0 zurück geben
    int CMDataBase::Init(void)
    {
    	OpenXml(sFileNameDrops);
    	OpenXml(sFileNameOthers);
    	// Einen richtigen Fehlschlag gibts noch nicht, deshalb immer 0 zurück geben
    	return 0;
    }
    
    int CMDataBase::OpenXml2(AnsiString sFileName)
    {
    	if (xFile.OpenXml(sFileName.c_str()))
    	{	// Datei konnte geöffnet werden
    		return true;
    	}
    	else return false;
    }
    
    int CMDataBase::OpenXml(AnsiString sFileName)
    {
    	if (xFile.OpenXml(sFileName.c_str()))
    	{	// Datei konnte geöffnet werden
    		return true;
    	}
    	else return false;
    }
    
    // Das übergebene Item wird zur Database hinzugefügt
    // Achtung, es wird nicht geprüft, ob das Item schon einmal in der Datenbank ist
    // Dafür vorher testen
    int CMDataBase::AddItem(SItem *Item)
    {
    	arItems.Length = nItems + 1;
    	arItems[nItems].bChanged = true;	// Da Item neu
    	arItems[nItems].Item = *Item;
    	return true;
    }
    
    #pragma package(smart_init)
    

    Die Funktion welche Funktioniert ist die OpenXml. Nicht funktionieren AddItem und OpenXml2(Die Kopie). Mit nicht funktionieren ist gemeint, das ich sie zwar von einer anderen Klasse aufrufen kann und der Comiler keine Fehler meldet, nur der Linker sagt das die Funktionen nicht vorhanden wären. Gross-/Kleinschreibung stimmt, das hab ich paar Stunden lang überprüft.



  • Ich weiß nicht ob es Dir hilft, versuch aber mal allo obj, lib, tds u. a. Dateien zu löschen und das Projekt neuzukompilieren. Manchmal bewirkt es Wunder.



  • Mordamir,
    suche in Deinen Projekt-Pfaden auch mal nach verwaisten Code-Dateien, die eventuell alte Versionen Deiner Klasse enthalten. Sowas entsteht, wenn man z.B. eine Unit via "Save As ..." umbenennt ...



  • Und lösche alle .il, .csm und .# Dateien (evtl. in anderen Verzeichnissen). Vielleicht verschluckt sich der Linker beim Versuch das Projekt incrementell zu linken.



  • Das löschen der *.obj und *tds Dateien hat nicht geholfen, mit den anderen Endungen hab ich nichts gefunden.
    Hab das Projekt dann mal ohne cached precompiled headers neu machen lassen, und siehe da, es funktioniert. 🙂
    Das hasse ich am programmieren: Wenn man sich mit Problemen rumärgern muss, die eigentlich keine sein sollten.


Anmelden zum Antworten