Komischer Fehler in Funktionsrückgabe

sTEk

Erfahrenes Mitglied
Ich hab da ein Problem, dass mich langsam fertig macht.
Folgender Sachverhalt:

Ich habe eine DLL geschrieben und dynamisch eingebunden, das klappt auch super.
Code:
void CTEDSView::RegistryLesen(CString& Hersteller, int& ln, int& br)
{
    HMODULE handle;
    handle = LoadLibrary("teds01.dll");

    if (handle != NULL)
    {
        typedef void (*DLLFUNC) (CString& Name, BOOL Lesen);
   
        DLLFUNC func = (DLLFUNC)GetProcAddress(handle, "Hersteller");
  
        if (func) 
            func(Hersteller, 1);
    }
    FreeLibrary(handle);
}
In dieser DLL schreibe und lese ich aus der Registry Werte. Dazu habe ich eine Klasse eingebunden, die das schön erledigt. Auf die Funktionen dieser Klasse greife ich mittels globaler Funktionen der DLL zu - folgendermaßen:

Code:
TEDS01_API void Hersteller(CString& Name, BOOL Lesen) {
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    CRegistry Registry;
    CString Nam;

    if(!Registry.VerifyKey(HKEY_LOCAL_MACHINE, m_Pfad))        // Überprüfen, ob Schlüssel existiert
        Registry.CreateKey(HKEY_LOCAL_MACHINE, m_Pfad);        //    wenn nicht > Erstellung

    Registry.Open(HKEY_LOCAL_MACHINE, m_Pfad);                // Öffnen der Registry

    if (Lesen) {
        if (Registry.VerifyValue("Hersteller")) {            // Überprüfen, ob Wert bereits existiert
            Registry.Read("Hersteller", Nam);                //    ja > auslesen
            Name=Nam;   hier liegt der Fehler  
            Registry.Close();    }                            //         Schließen der Registry
        else
            Nam ="";
        return; 
    }//         Rückgabe
    else {                                                    //    nein >
        Registry.Write("Hersteller",Name);                    //         Modellbezeichnung schreiben
        Registry.Close(); }                                //         Schließen der Registry
}
Nun bringt er mir ständig einen Debug Assertian Fehler mit Hinweis auf einen _CrtIsValidHeapPointer(pUserData) in einer dbgheap.c, wenn ich versuche , den ausgelesenen Wert zurück zu bekommen. Die Stelle, an der der Fehler auftritt, habe ich oben gekennzeichnet.

Was mache ich verkehrt?
 
Zuletzt bearbeitet:
Ich denke, du solltest auf ein CString-Objekt als Übergabeparameter verzichten und stattdessen lieber einen Zeiger verwenden. Sonst gibt es wahrscheinlich Probleme bei der Übergabe an eine DLL-Funktion. Vielleicht klappt's so:
C++:
// DLL
TEDS01_API void Hersteller(void *pParam, BOOL Lesen)
{
    // ...

    CString *pName = (CString *)pParam;

    // ...
}

 // Aufruf
func((void *)&Hersteller, 1);
Gruß
MCoder
 
Danke Dir - habe gerade etwas gefunden, dass die Fehlermeldung wie Du bereits sagtest durch einen Speicherzuordnungsfehler kommt.

Leider bekomme ich jetzt nichts heraus, wenn ich in der DLL versuche, den von der Funktion zurückgegebenen CString auf den pParam-Zeiger zu schieben:

Code:
...
CString Nam;
...
Registry.Read("Hersteller", Nam);                //   CString kommt richtig zurück

pParam=&Nam;    bringt nichts

Da ich mich mit den Zeigern erst langsam anfreunde, hab ich da noch so meine Schwierigkeiten.
Wie bekomme ich den Zeiger pParam auf den Wert von Nam, damit ich den CString in meinem Hauptprogramm nutzen kann?

Code:
void CTEDSView::RegistryLesen(CString& Hersteller, int& ln, int& br)
...
func((void*)&Hersteller, 1);
AfxMessageBox(Hersteller);   bleibt leer
 
Zuletzt bearbeitet:
Leider kommen da folgende Fehler:
error C2100: Zeigeroperation ungueltig
error C2679: Binaerer Operator '=' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'class CString' akzeptiert (oder keine geeignete Konvertierung moeglich)
 
Sorry, Tippfehler von mir. Ich meinte:
C++:
CString *pName = (CString *)pParam;
CString Nam;

// ...

*pName = Nam;
Gruß
MCoder
 
Danke für Deine schnelle Antwort.
Leider kommt dann der gleiche Fehler wie ganz am Anfang. :(

Ich habe jetzt raus bekommen, dass der Debug-Fehler immer nur dann kommt, wenn der CString-Wert (Nam) mit einem String belegt ist und dann die Pointerzuweisung erfolgt. Wenn er leer ist (also nur deklariert) passiert nichts. Ist irgendwie komisch.
 
Zuletzt bearbeitet:
Bekommst du den Fehler auch, wenn du mal einem festen String zuweist, also etwa sowas wie: *pName = "irgendwas"; ?

Gruß
MCoder
 
Ja, bekomm ich - das hatte ich schon probiert.
Wenn ich die Zuweisung mal in einem extra Programm ausprobiere klappt ja auch alles wie es soll. Es muss also mit der DLL-Geschichte zu tun haben, leider sind das meine ersten Gehversuche mit DLLs.
Ich bin mit meinem Latein langsam am Ende. :(
 
Zuletzt bearbeitet:
Dann denke ist, dass das Übergeben von MFC-Objekten an eine DLL grundsätzlich nicht vernünftig funktioniert, hab's auch selber noch nie ausprobiert. Beschränke dich also lieber auf einfache Datentypen, wie etwa einen char-Buffer für die Strings.
Könnte bei dir vielleicht so aussehen:
C++:
// DLL
TEDS01_API void Hersteller(char *pBuffer, int nBufferSize, BOOL Lesen)
{
    CString Nam;

    // ...
    
    int nStringSize = Nam.GetLength();
    
    if( nStringSize < nBufferSize )
    {
        strncpy(pBuffer, Nam.GetBuffer(nStringSize), nStringSize);
        pBuffer[nStringSize] = 0;
        Nam.ReleaseBuffer();
    }
    else
    {
        pBuffer[0] = 0;     
    }
    
    // ...
}

// Aufruf
    
char pBuffer[1024]; // sollte auch für lange Texte reichen
func(pBuffer, sizeof(pBuffer), 1)
CString Hersteller = pBuffer;
Gruß
MCoder
 
Zurück