Debugger Problem im VB6 Pro mit SQL Aufruf

maj7

Grünschnabel
Hallo,

ich arbeite an einer Anbindung unter VB6 an eine Oracle Datenbank. Diese wird über eine in C++ programmierte dll angespprochen, in der alle SQL Routinen als Funktionen bereitgestellt werden und der Datenaustausch über Types realisiert ist.

Mein Problem liegt darin das ich im Debugger von VB6 jedesmall nach dem ersten Select Aufruf einen kopletten Absturz der IDE habe und es mir damit nicht möglich ist das Projekt zu debuggen.

Wenn ich die kompilierte exe starte funktioniert die Routine einwandfrei auch wenn ich aus der c++ dll heraus debugge tritt dieser Fehler nicht auf.

Außerdem laufen die Insert Into sowie Update Befehle durch den Debugger in VB6 ebenfalls ohne Probleme.

Hat irgendjemand eventuell eine Idee an was das liegen könnte?

Vielen Dank

maj7
 
Wie hast du die dll denn eingebunden?

Für mich hört sich das an als ob du unterschiedliche Versionen der dll registriert hast. Die IDE hat mit "falsch" registrierten Dlls immer Probleme (Überprüfe mal den Pfad unter Projekt Verweise)

Durchsuche mal dein System nach der c++ Dll und schmeiss alle bis auf die benötigte raus. Dann lass Microsofts Regedit mind. 3 x laufen und registriere nur die benötigte dll

Grüsse bb
 
Hallo bb,

ich hab die jede einzelne Funktion der c++ dll über einen 'declare Function' in einem eigenen Modul eingebunden.

Bsp:
Declare Function ReadConnectionFile Lib "<pfad>" (ByRef Anmeldedaten As t_ADO_Connection, ByVal FileName As String) As Long

Gruss maj7
 
O.K. das macht die Sache nur deutlich schwieriger ! In diesem Fall wäre es nicht schlecht wenn du mal den entspechenden Code bis zum Absturz deiner IDE postest. Natürlich mit Deklaration der aufgerufenen Verbindungen bis zum Absturzzeitpunkt

Grüsse bb
 
' Datenbankverbindung herstellen
If bGKCConnect = False Then
If GKC_DLL_Aufruf.ADOOpenConnection GKC_Connection.sUser, sPassword, GKC_Connection.sSchema) = 0 Then
bGKCConnect = True

Else
bGKCConnect = False
MsgBox ("Verbindungsaufbau zur Datenbank gescheitert")
Exit Sub
End If
End If

Die Verbindung funktioniert auf jeden Fall!


' laden aus DB
Select Case Select_Kopfdaten(tKopf, tZuletzt, tArtikelnummern, strKdVorgangsNr, _ lPositionsNr)

Case 0 ' laden aus DB war erfolgreich

Case -1 ' Funktion erfolgreich aber keine Daten vorhanden

' MsgBox ("Laden aus Datenbank erfolgreich aber keine Daten vorhanden! _(Select_Kopfdaten)")

Case -2 ' Funktion gescheitert
MsgBox ("Laden aus Datenbank konnte nicht ausgeführt werden! _(Select_Kopfdaten)")

Case -3 ' Schlüsselwerte enthalten Defaultwerte
MsgBox ("Die Schlüsselparameter Kundenvorgangsnummer oder _ Positionsnummer enthalten _ Defaultwert! (Select_Kopfdaten)" & vbCrLf & _
"PosNr = " & CStr(lPositionsNr) & vbCrLf & _
"KdVorgangsnummer = " & CStr(strKdVorgangsNr))

End Select

Und sobald der Select abgeschickt wird stürtzt die komplette IDE ab.

Wie gesagt der ganze Vorgang läuft in der kompellierten exe einwandfrei durch genauso wenn ich aus der C++ dll heraus debugge läuft das genauso und die übergebenen Werte passen dort auch nur aus dem VB6 Debugger herraus nicht.
 
Zuletzt bearbeitet:
Also abgesehen von einem Klammerfehler hier
Visual Basic:
If bGKCConnect = False Then
If GKC_DLL_Aufruf.ADOOpenConnection GKC_Connection.sUser, sPassword, GKC_Connection.sSchema) = 0 Then
bGKCConnect = True
konnte ich noch nichts erkennen wie ist denn die Rückgabe der Api / Bzw. die Definition

Visual Basic:
select_Kopfdaten(tKopf, tZuletzt, tArtikelnummern, strKdVorgangsNr, _
    lPositionsNr)

PS: benutze bitte die Tags [code=vb] oder [CODE] dann ist der code etwas lesbarer ;-)
 
Hallo bb,
der Klammerfehler ist beim kopieren passiert danke für den Hinweis mit den Tags.

Code:
DECL_SPEC_DLL_EXPORT long STD_CALL Select_Kopfdaten(s_Kopf &S, s_Zuletzt &S2, s_Artikelnummern &S3, char *cKdVorgangsNr, long lPositionsNr)
{
	CString sFUNC_NAME = "Select_Kopfdaten --> s_Kopf";		// Funktionsname der 
															// aktuellen Funktion ...
	
	long lretVal = -1;
	char chTmpVar[300];										// Dient zum Auslesen der Werte aus der DB und 
	memset( chTmpVar, '\0', sizeof(chTmpVar) );				// zur Übergabe an die entsprechenden Variablen.


	// Das SQL - Statement wird aufgebaut.
	if( (strcmp(ChrTrim(cKdVorgangsNr), C_CharInitValue) == 0) || (lPositionsNr == C_LongInitValue) )
		return -3;
	else
		cSql.Format("SELECT * FROM %s WHERE %s = '%s' AND %s = %d", C_GKC_TBL_KOPFDATEN, 
		C_GKC_FD_KD_VORGANGS_NR, cKdVorgangsNr, C_GKC_FD_POSITIONS_NR, lPositionsNr);

	// Fehlerbehandlung wird gestartet ....
	try
	{
		// Das Recordset wird mit dem SQL - Statement gefüllt und ausgeführt.
		rs = adoConn->Execute((LPCTSTR)cSql, NULL, 0);
		
		// Das Recordset wird bis zum Ende ausgelesen.
		while (!rs->EOF)
		{
			//
			// Die Daten aus dem Recordset wird dem S übergeben.
			// ------------------------------------------------------------------------------
			//
			// Mittels dieser Funktion wird ein Eintrag aus dem Feld ausgelesen. -- Anfang
			//
			// Der ausgelesene Char - Wert wird erstmals in chTmpVar geschrieben, ...
			GetADOFieldContent(rs, C_GKC_FD_KD_VORGANGS_NR,		chTmpVar,	C_CharInitValue);
			// Danach wird über die Funktion memcpy dieser Wert in die richtige Variable geschrieben.
			memcpy(S.Kd_Vorgangs_Nr, chTmpVar, sizeof(S.Kd_Vorgangs_Nr));
			// Nach der Übergabe an die entsprechenden Variable muss chTmpVar wieder genullt werden.
			memset( chTmpVar, '\0', sizeof(chTmpVar) );
// Hier werden die einzelnen Daten aus der Tabelle geholt nach dem obigen Beispiel
// ...
			// Der Pointer rs muss, trotz dass nur ein Datensatz ausgewertet wird auf den
			// auf den nächsten Datensatz gesetzt werden, damit das EOF erreicht wird.
			//
			lretVal = 0;
			rs->MoveNext();
		}
		// Das Recordset wird geschlossen.
		rs->Close();
		
	}	
	// Wenn bei der Überwachnung von try ein Fehler auftritt, wird unter 'catch'
	// die Fehlerbehandlung durchgeführt.
	catch (_com_error &e)
	{
		// Eine Messagebox mit der Fehlerbeschreibung wird ausgegeben.
		CString strErrOutPutMessage;	// Variable für Fehlermeldung

		// Die Variable zur Ausgabe des Fehlers wird befüllt.
		strErrOutPutMessage.Format("%s \n Fehler in der Funktion: %s",
									(LPCTSTR)e.Description() ,sFUNC_NAME );
		// Die Message mit der Fehlerbehandlung wird ausgegeben.
		AfxMessageBox((LPCTSTR)strErrOutPutMessage, MB_ICONSTOP);

		//Das Fehlerprotokoll wird gefüllt.
		WriteErrorFile((LPCSTR)C_ErrFile, (LPCSTR)cSql);

		// Da die Funktion einen Fehler enthält wird diese hier mit -2 abgebrochen.
		return -2;
	}

	// Die Funktion ist ordnungsgemäß abgelaufen
	return lretVal;
};
Dies ist der Code in der C++ Datei.

Gruss
maj7
 
Also ich konnte jetzt leider da nicht wirklich was erkennen. (sieht ja soweit richtig aus)

Übernimm die Rückgabe deiner Funktion "select_Kopfdaten" doch mal vor der Select Anweisung explicit in einer long Variablen auf.

Ein weiterer Ansatz wäre die Verwendung von anderen Datentypen für Strings nach dem schema hier:
http://www.activevb.de/rubriken/kolumne/kol_4/cpptovbtypen.html

aber da es zur Laufzeit bei dir funktioniert scheint mir das nicht so erfolgsversprechend zu sein.
 
Wenn der Rückgabewert auf eine Long Variable gelegt wird stürtzt es nicht sofort ab sondern liefert noch eine Fehlermeldung:
- Der Vorgang "read" konnte nicht auf dem Speicher durchgeführt werden

Danach stürzt die IDE dann ab.

Gruss maj7
 

Neue Beiträge

Zurück