Dann sollte auch noch der Kompilermeckern bei der entsprechenden Interface-Datei von Unit, weil es die entsprechende Methode nicht mehr gibt. Das müsste in etwa so eine Zeile sein:
Hier wird sich der Kompiler melden, weil dann currCombatStr nicht mehr da ist. Derzeit scheint es so zu sein, dass die Methode noch da ist, aber weil es keine Implementierung der Methode gibt (weil du sie auskommentiert hast), kommt es dann beim Aufruf zu deiner Fehlermeldung.Code:.def("currCombatStr", CyUnit::currCombatStr)
(Aber eigentlich müsste sich doch der Linker melden, weil der die Definition nicht finden kann. )
Na, in der CyUnitInterface1.cpp hatte ich die fraglichen Funktionen auch brav abgemeldet.
Ich habe sie übrigens in der Zwischenzeit umgeschrieben, so dass sie nun zu meinen Änderungen (halbwegs) passen. Genaueres weiß ich allerdings noch nicht, weil ich im Moment eine Zugriffsverletzung bei CvUnit::getProfession() bekomme - warum auch immer.
Es ist ja nun nicht so, als sei diese Funktion als übermäßig fehlerträchtig anzusehen...Code:ProfessionTypes CvUnit::getProfession() const { return m_eProfession; }
Es ist zwar richtig, dass die entsprechende Unit keine Profession hat, aber das ist ja gang und gäbe. Vor allem ist das in einem bestehenden Spielstand, der hätte also eigentlich auch früher schon in die Knie gehen sollen...
Es gibt da nur einen Grund für eine Zugriffsverletzung und der ist, dass m_eProfession einfach keine Speicherzuweisung hat. Du musst m_eProfession mindestens beim erstellen der Einheiten mit einen Standardwert belegen für "Nichts". Meistens ist das -1 bzw wird dies über Enumeration häufig -1 gesetzt.
edit: siehe einfach CvUnit::reset an. Dort werden die Standardwerte für alle anderen Werte gesetzt.
Geändert von rucivfan (31. Oktober 2014 um 13:27 Uhr)
Ja, -1 als Wert hat die Profession ganz sicher nicht, eher irgendwas um die -8000234234 (so aus dem Kopf heraus). Der Witz ist, dass ich mit Professions absolut gar nichts gemacht habe, das ist noch der Zustand von vor meinen Änderungen. Trotzdem fliegt es mir jetzt gerade um die Ohren.
Kann es sein, dass eine Debug-DLL in der Hinsicht empfindlicher reagiert? Die Zugriffsverletzung als solche wird der Civilization.exe zugeordnet, aber es wurden in der Abbruchsmeldung Speicherstellen sowohl in der DLL wie in der .exe angegeben.
Dann trifft mit 100% meine Aussage oben zu. Wenn eine Adresse im Speicher nicht gesetzt wird, kann sonst was für einen Wert drinn stehen.
Ausrede!!!Der Witz ist, dass ich mit Professions absolut gar nichts gemacht habe, das ist noch der Zustand von vor meinen Änderungen. Trotzdem fliegt es mir jetzt gerade um die Ohren.
In wie weit empfindlicher? Wenn die release abstürzt, dann die debug erst Recht, aber man kann schauen wo es passiert. Ich kann nur sicher sagen, dass Win 7 empfindlicher als Win XP ist. Das war mal im BASE-Mod ein Problem als ich noch XP hatte.Kann es sein, dass eine Debug-DLL in der Hinsicht empfindlicher reagiert?
Das ist richtig so. Die Exe ruft ja schließlich Code aus der DLL auf!Die Zugriffsverletzung als solche wird der Civilization.exe zugeordnet, aber es wurden in der Abbruchsmeldung Speicherstellen sowohl in der DLL wie in der .exe angegeben.
siehe daZitat von rucivfan
Naja, ich verwende halt einen alten Spielstand, den ich mit der Release-DLL (= alte DLL-Version) auch problemlos spielen konnte. Da war ich dann schon 20 Züge weiter.
Mit der neu kompilierten Debug-DLL ... peng.
Aus der CvUnit::reset:
m_eProfession = NO_PROFESSION;
Und NO_PROFESSION ist mit -1 enumeriert.
Hmm.. komisch.
Es kann auch indirekt sein. Nehmen wir mal an, es gibt die Einheit garnicht. Dann wurde der Wert auch nie mit reset gesetzt. Und trotzdem wird versucht, auf die nicht existierende Einheit zu zugreifen.
Du musst mal im Stack eine Etage tiefer schauen. Besser: Poste den relevanten Teil des Stackes. Relevant: Liegt im SDK.
Doch, die Einheit gibt es, mit meiner neuen, feinen Struktur konnte ich mir nämlich ihren Namen ansehen...
Stack poste ich später, ich muss jetzt erst mal weg.
Feine Struktur sagt schon alles. Du hast keine Savegameskombatiblität, wenn du keinen Anpasscode geschrieben hast. Genaueres kann ich ohne Vollständigen Code des davor und danach nicht sagen. Aber poste erstmal den Stack.
Die brauche ich in diesem Falle auch nicht. Meine Struktur wird mit allen kampfrelevanten Daten der Einheiten gefüllt, damit sich die aufrufenden Funktionen dann daraus bedienen können. Das geschieht zur Laufzeit, und schon die vorherige Runde, resp. die vorherige Kampfwertberechnung ist für diesen Vorgang egal - und muss es auch sein.
Yep. Ich muss mich jetzt erst noch durch die ganzen Haltepunkte klicken
Die Stackliste und darunter in den Spoilern die entsprechenden Code-Ausschnitte.
getProfession hatte ich ja schon gepostet.Code:> CvGameCoreDLL.dll!CvUnit::getProfession() CvGameCoreDLL.dll!CvUnit::noDefensiveBonus() CvGameCoreDLL.dll!CvUnit::CBM_CombatStr(const CvUnit * pAttacker, const CvUnit * pDefender, const CvPlot * pPlot, CBM_CombatDetails * pCBM_CombatDetails) CvGameCoreDLL.dll!getCombatOdds(const CvUnit * pAttacker, const CvUnit * pDefender) CvGameCoreDLL.dll!CvUnit::isBetterDefenderThan(const CvUnit * pDefender, const CvUnit * pAttacker, bool bBreakTies) CvGameCoreDLL.dll!CvPlot::getBestDefender(PlayerTypes eOwner, PlayerTypes eAttackingPlayer, const CvUnit * pAttacker, bool bTestAtWar, bool bTestPotentialEnemy, bool bTestCanMove) CvGameCoreDLL.dll!CvPlot::updateCenterUnit() CvGameCoreDLL.dll!CvMap::updateCenterUnit()
Das ist der Wert für eProfession: eProfession -858993460
Enumeration der ProfessionTypes:
Achtung Spoiler:
noDefensiveBonus()
Achtung Spoiler:
CBM_CombatStr(...) - Ausschnitt
Achtung Spoiler:
getCombatOdds(...) - Ausschnitt
Achtung Spoiler:
isBetterDefenderThan(...) - Auschnitt
Achtung Spoiler:
getBestDefender(...) - Ausschnitt
Achtung Spoiler:
Und der Vollständigkeit halber noch die Fehlermeldung:
Unbehandelte Ausnahme bei 0x05660f71 (CvGameCoreDLL.dll) in Colonization.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x000000f0.
Geändert von Commander Bello (31. Oktober 2014 um 17:31 Uhr)
mmh, CvMap::updateCenterUnit() bzw CvPlot::updateCenterUnit() wählt die Einheit, die als erstes grafisch auf den Feld angezeigt werden soll. Ehrlich gesagt, würde ich hier weiter plädieren, dass eine Einheit als Übergabewert ein NULL-Pointer ist.
Und zwar denke ich, dass pAttacker als Übergabewert gleich NULL (0) ist.
edit: Dann müsste der Fehler in getCombatOdds(...) liegen. Dort wird schließlich auf pAttacker zugegriffen.
Respekt!
pAttacker ist tatsächlich NULL in getCombatOdds(...).
Und den Fehler habe offensichtlich ich gemacht , denn ich habe in der isBetterDefenderThan(...) noch den Vergleich der Wahrscheinlichkeiten eingebaut.
Dass du das so auf einen Blick gesehen hast... Donnerwetter!
Ok, da muss ich mir mal Gedanken machen. Jetzt werde ich den Teil einfach auskommentieren und noch mal laufen lassen....
Die unendliche Geschichte geht weiter...
Nachdem die updateCenterUnit()-Funktionen in den Cv::Map/CvPlot durchlaufen wurden, bricht das Spiel ab, weil eine Prozedur nicht gefunden wurde.
Nun zermartere ich mir das Schwachhirn, was ich wohl auskommentiert/geändert haben könnte, und nun gesucht wird.
Mein Problem ist, dass ich für die void CvMap::updateCenterUnit() keinen Aufruf finde, und daher nicht weiß, um welche Prozedur es sich handeln könnte, noch, an welcher Stelle es in der DLL dann weiter gehen könnte.
Gibt es in VC2010 eine Möglichkeit, alle zurückliegenden Änderungen an der Projektmappe anzuzeigen (also auch die von vorherigen Sessions)?
Achtung Spoiler:
Geändert von Commander Bello (01. November 2014 um 14:41 Uhr)