Frage

Ich habe eine Klasse mit einer statischen Methode, die in etwa wie folgt aussieht:

class X {
    static float getFloat(MyBase& obj) {
        return obj.value();  // MyBase::value() is virtual
    }
};

Ich rufe es mit einer Instanz von MyDerived der MyBase Unterklassen:

MyDerived d;
float f = X::getFloat(d);

Wenn ich die OBJ-Datei, die X in meine ausführbaren Datei verknüpfen, funktioniert alles wie erwartet. Wenn ich erwarte 3.14 zu bekommen, erhalte ich es.

Wenn ich eine LIB erstellen, die die X.OBJ Datei und Link in der LIB enthält, es bricht. Als ich getFloat () aufrufen, zurückkehr es -1. # IND00 . Ist das eine Art von Sentinel-Wert, der mir was falsch hier sagen sollte?

Ist etwas anders, wenn man in einem lib verknüpfen anstatt OBJ direkt?

Ich erhalte keine Compiler-Warnungen oder Fehler.

Bearbeiten:
Ich bin mit Visual Studio 2005 auf Windows XP Pro SP3. Um sicherzustellen, dass ich nicht die Verknüpfung alte Dateien, geklont ich den Wert () -Methode in eine neue Wert2 () -Methode und genannt, statt. Das Verhalten war das gleiche.

Bearbeiten # 2:
Also, wenn ich in den Anruf mit meinem Debugger verfolgen, ich finde, dass es nicht in meinen Wert wird () Methode überhaupt. Stattdessen geht es in einen anderen (nicht verwandten) -Methode. Das macht ich denke, meine VTable beschädigt ist. Ich denke, das Verhalten Ich sehe muß eine Nebenwirkung von einem anderen Problem.


Gelöst! (dank Vlad)
Es stellt sich heraus, dass ich die eine Definitionsregel verstoßen (ODR), obwohl es nicht klar, aus dem Code war ich gepostet. Dieses ist ein großer Artikel aus den Visual C ++ Jungs, die das Problem und eine Art und Weise erklärt, es aufzuspüren. Das / d1reportSingleClassLayout Compiler-Flag ist ein fantastisches Lernwerkzeug.

Wenn ich das Layout meiner Klasse für MyBase abgeladen und MyDerived in den zwei verschiedenen Projekten, fand ich Unterschiede zwischen dem rufenden Code und dem Bibliothekscode. Es stellt sich heraus, dass ich hatte einige #ifdef Blöcke in meine Header-Dateien und die entsprechenden #define Aussage war in der vorkompilierte Header für das Hauptprojekt, aber nicht in dem Teilprojekt (die Bibliothek ). Habe ich erwähnt, wie böse ich denke Präprozessormakros sind?

Wie auch immer, ich bin Entsendung nur das Zeug, weil es an jemand anderen nützlich sein könnten. Diese Frage war auch sehr hilfreich für mich.

War es hilfreich?

Lösung

Dieses Problem tritt auf, wenn die lib und die ausführbaren Datei haben mit verschiedenen Definitionen der MyDerived Klasse kompiliert werden wurden (dh verschiedene Versionen der .h / .hh / .hpp-Datei, die MyDerived deklariert. Völlig sauber und Wiederaufbau Ihre Projekte. Barring dies, verschiedene Compiler-Optionen könnte verantwortlich sein, auch wenn es eher unwahrscheinlich ist.

Wenn das Problem nach dem alles von Grunde auf dem Wiederaufbau weiterhin besteht, dann Nagel durch ein Dummy-MyDerived Objekt innerhalb getFloat instanziiert wird, in der Bibliothek. Verwenden Sie den Debugger den vtable des Dummy MyDerived (instanziiert in der Bibliothek) und der vtable der MyDerived Objektreferenz als Parameter (instanziiert in der ausführbaren Datei.) Übergeben vergleichen Etwas zum Auge springen sollte sofort.

Andere Tipps

Da ein lib ist nur ein Container, wenn Sie die gleiche OBJ-Datei in beiden Fällen verknüpft werden dann als Brian sagt, sie sollten nicht (nicht?) Ein Unterschied sein.

Eine Sache, zu sehen ist, wenn man die Definition von MyBase geändert Sie offensichtlich neu kompilieren müssen sowohl die Bibliothek und den Code es zu benutzen. Zum Beispiel, wenn Sie eine neue virtuelle Methode hinzugefügt, bevor der Wert Methode MyBase, dann, dass die Bibliothek, da die V-Tabelle von Offset-Wert würde vermasseln würde anders sein.

Es sollte keinen Unterschied. So stellen Sie sicher, dass die H-Dateien Sie entsprechen dem LIB sind inklusive, die Sie genau verknüpfen. Ich vermute, Sie können auf eine alte LIB-Datei werden zu verknüpfen.

Wenn Sie Visual Studio verwenden, statt explizit die LIB-Datei angeben, klicken Sie einfach rechts auf dem Projekt und stellen Abhängigkeiten das LIB-Projekt. So können Sie sicher sein, wird es verwendet die richtige LIB-Datei.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top