Problem mit Heap Corruption
-
Hallo ihr lieben,
ich stelle mich mal kurz vor, da das hier mein erster Post in eurem Forum ist. Mein Name ist Mats, ich komme aus der Nähe von Hamburg, bin 27 und beruflich als Techniker beim Fernsehen unterwegs. Seit meiner Jugend beschäftige ich mich hobby-mäßig mit programmierung, habe mich aber mehr mit Sprachen wie PHP beschäftigt.
Jetzt stehe ich vor einer großen Herausforderung, die ich hoffentlich noch gewuppt kriege. Jetzt zu meiner Problematik:
Bei einem Volleyballspiel werden alle Statistiken mittels der Software "Datavolley" erfasst und in irgendeiner Datenbank gespeichert. Diese Daten möchte ich gerne nutzen um sie in unser TV-Grafiksystem zu speisen.
Zum Auslesen der Daten habe ich von dem Hersteller der Datavolley-Software ein paar Daten bekommen. Unter anderem eine Rundll.exe die einem die Daten in einem Fenster ausspuckt. Anbei ist auch noch ein Code und eine .dll mit dem man arbeiten kann / soll.
Da ich diese Daten einfach in einer Textdatei brauche, um sie dann wieder mit meiner Grafiksoftware lesen zu können, dachte ich mir, ich probiere es mal aus.
Darauf hin habe ich mir Virtual Studio C++ Express heruntergeladen und einfach mal den Code da reingeklatscht. Das kompilierte Programm lässt sich in der Konsole ausführen. Schreibt mir auch die Werte in die Konsole, kommt dann aber mit der Meldung:
Debug error:
Programmpfad
HEAP CORRUPTION DETECTED after normal block .....
CRT detected that the application wrote to memory after end of heap buffer.Ich hoffe sehr, dass ihr mein Problem versteht. Sonst fragt bitte einfach. Brauche das Ganze am kommenden Wochenende und da die Funktion ja bereits gegeben ist stört eigentlich nur die Fehlermeldung.
Ich bedanke mich schonmal ganz herzlich für all eure Hilfe!Lieben Gruß
MatsAnbei noch mein Code.
// SampleDLL.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "windows.h" #include "stdio.h" typedef struct TDVParamsStruct { char *PathSource; // Path containing STATISTICS*.TOT int IdTeam; // 0=Home, 1=Visitor int IdPlayer; // 0..99 Player Jersey Number, 100=Team, 101..106 Rotation 1..6 int Skill; // 0=Tot, 1=Serve, 2=Reception, 3=Attack, 4=Block, 5=Dig, 6=Set, 7=Free Ball int SetN; // 0=Match, 1..5 Set int IDCall; // 0=Fixed value } TDVParams; typedef struct TDVOutPtsErrStruct { int Pts; // Points int Err; // Errors int Tot; // Total events } *TDVOutPtsErr; typedef UINT (CALLBACK* LPFNDLLFUNC1)(TDVParams, TDVOutPtsErr); int main(int argc, char* argv[]) { printf("an"); TDVParams Par; TDVOutPtsErr ParFunc = NULL; ParFunc = (TDVOutPtsErr) malloc(sizeof(TDVOutPtsErr)); char par[36] = "C:/"; // Path containing dv3STATISTICS*.tot Par.PathSource = par; Par.IdPlayer = 100; Par.IdTeam = 0; Par.SetN = 0; Par.Skill = 0; HINSTANCE hDLL; // Handle to DLL LPFNDLLFUNC1 GetPointsErr; // Function pointer UINT uReturnVal; hDLL = LoadLibrary("DvStat.dll"); if (hDLL != NULL) { GetPointsErr = (LPFNDLLFUNC1)GetProcAddress(hDLL,"GetPointsErr"); if (!GetPointsErr) { // handle the error FreeLibrary(hDLL); free(ParFunc); return -1; } else { // call the function uReturnVal = GetPointsErr(Par, ParFunc); printf("Return = %d \n", uReturnVal); if (uReturnVal == 0){ //Print Output printf("Tot: %d \n", ParFunc->Tot); printf("Err: %d \n", ParFunc->Err); printf("Points: %d \n", ParFunc->Pts); } else { printf("Error"); FreeLibrary(hDLL); free(ParFunc); return -1; } } } FreeLibrary(hDLL); free(ParFunc); //return 0; }
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (alle ISO-Standards) in das Forum C (alle ISO-Standards) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Das ist alles Beispielcode des Herstellers oder hast du da etwas verändert?
Im Zweifelsfall hast du Release und Debug vermischt, d.h. DLL ist als Release übersetzt, das Programm dann aber als Debug gebaut.
-
Zeile 33 ist schon mal Quatsch. Weder ist sizeof(TDVOutPtsErr) die korrekte Größe für das, was hinterher gemacht wird, noch ist das malloc/free hier überhaupt angebracht. Das hat wohl irgendein Praktikant, der noch nie C (das ist C, kein C++) gemacht hat in der Mittagspause zusammen geschustert.
Da ich die Bibliothek nicht haben, kann ich es nicht testen. Noch habe ich die Spezifikationen der Bibliothek, so dass ich nur raten kann. Aber so mal fix über den Code gegangen, so dass er halbwegs richtig aussieht, würde ich folgendes ausprobieren:
// Die Datei nennen wir lieber SampleDLL.c, dann erkennt MSVC auch, dass dies C sein soll. #include "stdafx.h" #include "windows.h" #include "stdio.h" typedef struct TDVParamsStruct { char *PathSource; int IdTeam; int IdPlayer; int Skill; int SetN; int IDCall; } TDVParams; typedef struct TDVOutPtsErrStruct { int Pts; int Err; int Tot; } TDVOutPtsErr; // Kein '*' typedef UINT (CALLBACK* LPFNDLLFUNC1)(TDVParams, TDVOutPtsErr*); // Dafür hier ein '*' int main() // Wenn wir die Parameter nicht nutzen, führen wir sie gar nicht erst ein { HINSTANCE hDLL = LoadLibrary("DvStat.dll"); // In C müssen Variablen am Anfang des Scopes definiert werden printf("an"); // Niedlich if (hDLL != NULL) { LPFNDLLFUNC1 GetPointsErr = (LPFNDLLFUNC1)GetProcAddress(hDLL,"GetPointsErr"); // Variablen so lokal wie möglich if (!GetPointsErr) { FreeLibrary(hDLL); // free braucht's nun nicht mehr return -1; } else { TDVParams Par; // Variablen so lokal wie möglich TDVOutPtsErr ParFunc; // Einfach eine normale Variable UINT uReturnVal; char par[36] = "C:/"; // Folgendes ginge auch geschickter, aber ich will nicht alles umschreiben Par.PathSource = par; Par.IdPlayer = 100; Par.IdTeam = 0; Par.SetN = 0; Par.Skill = 0; uReturnVal = GetPointsErr(Par, &ParFunc); // Dann eben hier einen Zeiger auf die Variable übergeben printf("Return = %d \n", uReturnVal); if (uReturnVal == 0){ printf("Tot: %d \n", ParFunc.Tot); // hier . statt ->, da wir keinen Zeiger mehr vorliegen haben printf("Err: %d \n", ParFunc.Err); printf("Points: %d \n", ParFunc.Pts); } else { printf("Error"); FreeLibrary(hDLL); // Hier natürlich auch kein free return -1; } } } FreeLibrary(hDLL); // Und hier auch nicht return 0; // In C(89) ist return 0 kein default, wir müssen es schon angeben. }
Die vielen freeLibrarys sind noch etwas ungeschickt, aber ich wollte jetzt nicht alles neu schreiben.
-
Vielen Dank ihr lieben! Vor Allem an SeppJ.
Leider fehlt mir die nötige Kompetenz um Deine Änderungen im Detail nachvollziehen zu können, aber auf jeden Fall läuft das Ganze jetzt ohne Fehler.
Eventuell sollte ich Dir mal den Kontakt schicken und die verkaufst das reparierte Script an die Pfeifen. :p
Ich werde mich jetzt etwas in C schlau machen um noch die Dateiausgabe und einen Timer zu realisieren. Ich hoffe ich bekomme das hin, sonst gehe ich euch nochmal auf den Senkel.
Vielen Dank für die schnelle Hilfe. Tolle Forum!
Gruß
Mats