variant - Probleme?

lukasS

Erfahrenes Mitglied
Hallo,

seit längerem sitze ich an meinem kleinen Projekt und komme nicht weiter. Ich möchte ein kleines Frage/Anwort - Spiel programmieren. Dazu lese ich eine Access-DB über ADO aus.

In einer Methode lese ich eine komplette Zeile aus und schreibe die in ein CStringArray, nur leider klappt das nur ein bis drei mal, bis der Compiler (VC++ 6.0) mir die Meldung unhandled excepection ausspuckt. Das passiert wenn ich mit dem variant die ChangeType - Methode oder wenn ich beim RecordsetObj GetCollect aufrufe. Hier ist der Teil, der nicht das tut was ich will:

Code:
	_variant_t vRowData;
	for (long i = 0; i < m_arrColumns.GetSize(); i++)
	{
                 vRowData = m_pRs->GetCollect(_variant_t(m_arrColumns.GetAt(i)));//Abstruz
                vRowData.ChangeType(VT_BSTR); // oder ab und zu hier  
                arr.Add(vRowData.bstrVal);
	}

Erklärung zum Code:
m_pRs -> Recordsetobject
m_arrColumns -> CStringArray mit allen Spaltennamen
arr -> CStringArray in dem die Daten stehen sollen

Wenn der beim ersten Versuch abstürzen würde, ok, aber dass er ab und zu sogar beim dritten Mal abstürzt verstehen nicht.

m_arrColumns ist mit Werten gefüllt, das habe ich überprüft. Der stürzt immer bei der Methode ChangeType ab.

Hat jemand vielleicht eine Idee? Zur Not kann ich auch sogar das Projekt zuschicken.

Ich bin für jede Hilfe dankbar!

Lukas
 
Hm, ich kenne mich damit nicht so gut aus, aber du solltest die Exceptions auf jeden Fall mal fangen (try..catch) und nachsehen, was sie dir zu sagen haben.

GetAt() löst einen Assert-Fehler aus, wenn es Probleme gibt. Hast da etwas festgestellt? Asserts treten in Release-Builds nicht auf -- hast du eine Debugversion getestet?
 
Danke erstmal für die Hilfe,

mit try catch fange ich das ja schon ab. Dass man die Fehler mit den catch auslesen kann, davon habe ich gehört, aber nicht mehr. Bin eben ein C++ - Neuling.

Am CStringArray wird es nicht liegen, ich hab das getestet, indem ich die Werte reingeschrieben habe.

Könnte es vielleicht an irgendwelchen Speicherfreigaben liegen? Muss man die variants löschen?

Was meist du mit damit, ob ich eine Debugversion getestet habe?
 
mit try catch fange ich das ja schon ab. Dass man die Fehler mit den catch auslesen kann, davon habe ich gehört, aber nicht mehr. Bin eben ein C++ - Neuling.
Versuch mal das (ungetestet!):
Code:
try
{
  vRowData.ChangeType(VT_BSTR); 
}
catch( _com_error& e )
{
  // oh, eine Exception!
  // versuch mal:
  printf( e.ErrorMessage( ) ); 
  // weiss nix genaues, müsste mich selber einarbeiten
  // schau dir mal die MSDN Lib zu den Methoden an.

  // noch auf Fehler reagieren!
}

Könnte es vielleicht an irgendwelchen Speicherfreigaben liegen? Muss man die variants löschen?
Da bin ich z.Zt. überfragt -- wenig Erfahrung mit Com-Variants und CStringArrays. Ich rate ohnehin stattdessen zu boost::any und std:vector! ;)

Was meist du mit damit, ob ich eine Debugversion getestet habe?
VC++ lässt dich verschiedene Versionen erstellen. Die Release-Version ist optimiert und klein, und nur diese sollte an einen Kunden gehen. ASSERT() ist deaktiviert. Die Debug-Version ist nicht optimiert enthält zusätzlich Infos für den Debugger, um Debuggen zu ermöglichen. Die ausführbare Datei ist deshalb ziemlich fett. Darüber hinaus verhält sich eine Debug-Version relativ gutmütig in Bezug auf nicht richtig initialisierte Variablen.
 
Es wird unten im Debugfenster folgendes wiedergegeben:

Nicht abgefangene Ausnahme in quizzz.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.

Der Fehler tritt meistens bei der GetCollect() - Methode. Könnte es vielleicht an dem Recordsetobject liegen. Das hieße, ich müsste dann vor jedem Zugriff auf die Tabelle das RecObj schließen und dann neu öffnen? Nein oder, war ja nur ein Gedanke von mir.

Das Objekt ist ja nicht leer. Ich verstehe das nicht. Gibt es vielleicht eine andere Möglichkeit eine Zeile aus einer Access-DB mit dem RecordsetObj auszulesen?

Ich schaue mich mal nach anderen Möglichkeiten nochmal um.

Lukas
 
Hallo,

ich habe den Fehler entdeckt. Dummerweise habe ich das RecordsetObj nicht mit MoveFirst an die erste Position gesetzt. Kleiner dummer Fehler von mir, der mich aber tagelang nerven gekostet hat.

Danke nochmal für deine Hilfe Kachelator! Ich kanns immernoch nicht glauben.

Lukas
 
Zurück