wake-up-neo.com

Kritischer Fehler festgestellt c0000374 - C++ - DLL gibt den Zeiger aus dem zugewiesenen Speicher an C # zurück

Ich habe eine C++ - DLL, die einige Funktionen für meine Hauptanwendung von c # bereitstellt .. Hier versuche ich, eine Datei zu lesen, sie in den Speicher zu laden und dann Informationen wie den Zeiger auf geladene Daten und die Anzahl der Speicherblöcke in c # zurückzugeben. Die Dll liest die Datei erfolgreich in den Speicher, aber bei der Rückkehr zur Hauptanwendung stürzt das Programm aufgrund einer Heap-Beschädigung ab (Kritischer Fehler c0000374).

Der Code ist recht einfach und unkompliziert, und ich habe bereits einige ähnliche Dinge ohne Probleme gemacht. Allerdings konnte ich nicht herausfinden, was das Problem hier ausmacht. Ich habe versucht, Speicher mit "new", "malloc" und "GlobalAlloc" zuzuweisen. Codes sind wie folgt:

C++ MyDll:

typedef unsigned long         U32;

extern "C" __declspec(dllexport) int ReadFile(LPSTR Path, U32** DataPtr, U32* Count)
{
   FILE *fp;
   U32 *Data;
   CString tempStr(Path);
   long fSize;

   if(!(fp = fopen(tempStr, "rb"))) {
    return 0;
   }

   // Obtain File Size;
   fseek(fp, 0, SEEK_END);
   fSize =  ftell(fp);
   rewind(fp);

   Data = (U32 *)GlobalAlloc(0, fSize);
   if(Data == NULL) {
            fclose(fp);
            return -1;
    }

    // Copy file into the buffer.
        if(!(*Count = fread(Data, sizeof(U32), fSize / sizeof(U32), fp))) {
           fclose(fp);
           free(Data);
           return -2;
        }

   *DataPtr = (U32 *)Data;
       return 1;
}

C # -Anwendung:

        [DllImport(@"MyDll.dll", CallingConvention= CallingConvention.Cdecl)]
    private static extern int ReadFile([MarshalAs(UnmanagedType.LPStr)]string Path, out IntPtr dataPtr, out uint Count);

private void readDump(string Path)
{
    uint count = 0;
    IntPtr Data = new IntPtr();

   try{
       if(ReadFile(Path, out Data, out count) == 1) //The Program crashes just right after this statement
       {
           //Do Something ...
       }
    }
    catch() {}

}

Das Programm stürzt sowohl im Debug- als auch im Freigabemodus ab. Es sei denn, ich halte das Programm nach dem Laden der Datei im Debug-Modus an und rufe einige Speicherblöcke im "Direktfenster von Visual Studio" auf. Die Größe der zu ladenden Dateien beträgt ca. 64 MB und wir haben mehr als 2 GB freien RAM im RAM PC.

UPDATE: Ich habe bemerkt, dass einige Programme von Drittanbietern, die sie zuvor bearbeiteten, mit "Exception Code: c0000005" abstürzen, und einige andere seltsame Dinge in Windows 7 (dem Host) auftreten. Also habe ich den Code in einer anderen Windows-Installation getestet und alles scheint so zu funktionieren, wie es sollte. Also ist es wahrscheinlich das Windows 7. Nun, wie könnte ich das Problem beheben? "sfc/scannow" konnte kein Problem finden.

6
2i3r

Wenn Ihr Code in der Tat das ist, was oben gezeigt wird, sehe ich das Problem nicht. Wenn ich jedoch dieses Problem bekomme, liegt es manchmal daran, dass malloc/new/whatever Heap-Corruption entdeckt. Oft ist diese Corruption bereits im Programm aufgetreten, der Absturz wurde jedoch bis zum nächsten Aufruf von new/malloc verzögert.

Wenn Sie andere Dateien lesen oder andere Puffer zuweisen oder freigeben, bevor das obige ausgeführt wird und abstürzt, würde ich dort nach Problemen suchen. Vielleicht werfen Sie eine Reihe von Zusicherungen überall hin, wo Sie in Puffer schreiben, und überprüfen Sie die Grenzen und was Sie für Überschreitungen schreiben .. Tut mir leid, das ist keine konkrete Antwort, ich habe nicht genug Vertreter, um diesen Rat als Kommentar zu hinterlassen.

20
Freya301

Sie weisen die Ausgabedaten 2 mal zu. .. Einmal in C # als neu IntPtr und dann in C++ als GlobalAlloc und geben Sie den Zeiger zurück, der von GlobalAlloc zurückgegeben wird. Der von new intPtr zurückgegebene Zeiger ist also verloren gegangen.

1
Kalpesh