DLL Codeguard RessourceLeak
-
Hallo zusammen
Ich habe eine DLL erstellt, welche ich dynamisch in ein Projekt eingebunden habe.
Soweit so gut. Sobald ich jedoch die Funktion aus der DLL ausführe und denn Speicher der DLL freigebe (FreeLibrary), zeigt mir CodeGuard ein RessourceLeak an.Error 00049. 0x300010 (Thread 0x08E4): Resource leak: The memory block (0x1254C74) was never freed The memory block (0x01254C74) [size: 36 bytes] was allocated with SysGetMem Call Tree: 0x014C10B3 0x3267E2F5(=CC3260MT.DLL:0x01:07D2F5) 0x3267E813(=CC3260MT.DLL:0x01:07D813) 0x014A134C 0x7C92CBAB(=ntdll.dll:0x01:01BBAB) 0x7C926178(=ntdll.dll:0x01:015178) ...Ich kann leider mit der Meldung nicht viel Anfangen.
Die Funktion in der DLL bekommt als Parameter zwei Pointer(char und int). Der Fehler tritt selbst dann auf wenn ich alles in der Funktion auskommentiere.
Ich weiß langsamm nicht mehr weiter, wie ich den Fehler einkreisen kann.
Zu Erstellung der DLL habe ich das BCB Builder Tutorial verwendet.
Habe die memmgr.lib eingebunden, brauch ich die überhaupt? Verwende keine dynamisch RTL.
Ich hab noch was von Aufrufkonventionen gelesen, jedoch weiß nicht so recht etwas damit anzufangen.Ich hoffe es kann mir jemand helfen.
MfG Stephan
-
Hallo
die Meldung sagt, das du mit new oder malloc speicher anforderst, dann dann aber bis zum Ende des Programms nicht wieder ordnungsgemäß freigegeben wird.
Warum die Meldung kommt, können wir aber ohne relevanten Code nicht sagen. Du kannst deine Suche auf jedenfall auf deine dynamische Speicherverwaltung konzentrieren.bis bald
akari
-
Hallo zusammen
So etwas hab ich mir schon gedacht, allerdings verwende ich keins von beidem.
wie gesagt die dll Funktion ist momentan eine leere Funktion.
Es soll später eine Struktur mit Daten gefüllt werden die als Pointer gecastet nach int übergeben wird.DLL Funktion:
extern "C" __declspec (dllexport) void ExtractFileNameInfos(char *cFileName, int *iData) { /* int iCountDelimiters; int iSerialNumberLength; char cTemp[512]; strcpy(cTemp, cFileName); AnsiString sFileName = cTemp; FileNameInfos *Fni; Fni = (FileNameInfos *)iData; Fni->sFileExt = ExtractFileExt(sFileName); sFileName = ExtractFileNameWithoutExt(sFileName.UpperCase()); iCountDelimiters = CountDelimiters(sFileName, "_"); //check if file is an mdf file if(sFileName.Pos("MDF") == 0) { Fni->bMeasurementDataFile = false; } else { Fni->bMeasurementDataFile = true; return; } //extract date and time Fni->sDate = ExtractTextInDelimiters(sFileName, iCountDelimiters-5, iCountDelimiters-2, "_"); Fni->sTime = ExtractTextInDelimiters(sFileName, iCountDelimiters-2, iCountDelimiters+1, "_"); //check if file contains _P_ or _F_ if( (sFileName.Pos("_P_") == 0) && sFileName.Pos("_F_") == 0) { // Product_Serno_YYYY_MM_DD_HH_MM_SS.EXT 7 //Product_Ver_Serno_YYYY_MM_DD_HH_MM_SS.EXT 8 //Product.Ver_Serno_YYYY_MM_DD_HH_MM_SS.EXT 7 //extract serialnumber Fni->sSerialNumber = ExtractTextInDelimiters(sFileName, iCountDelimiters-6, iCountDelimiters-5, "_"); //extract product Fni->sProduct = ExtractTextInDelimiters(sFileName, 0, iCountDelimiters-6, "_"); } else { // Product_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 8 //Product_Ver_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 9 //Product.Ver_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 8 //Product-PCB_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 8 //extract Status Fni->sPassFail = ExtractTextInDelimiters(sFileName, iCountDelimiters-6, iCountDelimiters-5, "_"); //extract serialnumber Fni->sSerialNumber = ExtractTextInDelimiters(sFileName, iCountDelimiters-7, iCountDelimiters-6, "_"); //extract product Fni->sProduct = ExtractTextInDelimiters(sFileName, 0, iCountDelimiters-7, "_"); } // without P and F // Product_Serno_YYYY_MM_DD_HH_MM_SS.EXT 7 // Product_Ver_Serno_YYYY_MM_DD_HH_MM_SS.EXT 8 // Product.Ver_Serno_YYYY_MM_DD_HH_MM_SS.EXT 7 // // with P and F // Product_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 8 // Product_Ver_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 9 // Product.Ver_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 8 // Product-PCB_Serno_S_YYYY_MM_DD_HH_MM_SS.EXT 8 //exchange _ with . in product if(Fni->sProduct.LastDelimiter("_") != 0) { Fni->sProduct = ExchangeFirstCharacter("_", ".", Fni->sProduct); } //remove first char from serialnumber if length greater 7 and first char is 0 iSerialNumberLength = Fni->sSerialNumber.Length(); while(iSerialNumberLength > 7) { if(Fni->sSerialNumber[1] == '0') { Fni->sSerialNumber = Fni->sSerialNumber.SubString(2, iSerialNumberLength); } else { break; } iSerialNumberLength = Fni->sSerialNumber.Length(); } //extract fab code from serialnumber iSerialNumberLength = Fni->sSerialNumber.Length(); Fni->sFabCode = Fni->sSerialNumber.SubString(iSerialNumberLength - 6, 7); Fni->sFabCode = Fni->sFabCode.SetLength(2); Fni->sFabCode = Fni->sFabCode.Trim(); */ }Im Dll Headerfile wird noch eine Struktur definiert.
Schnittstellen CPP:
/******************************************************************************* Functionname: ExtractFileNameInfos Description: Parameter 1: char *cFileName Parameter 2: int *cData Return: int Author: History: 19.05.2006 first version *******************************************************************************/ int ExtractFileNameInfos(char *cFileName, int *cData) { TypeExtractFileNameInfos *ExtractFileNameInfos; int iReturn = 0; HINSTANCE hDll; //load dll hDll = LoadLibrary(DLL_NAME); //check dll handle if(hDll != 0) { //get function address ExtractFileNameInfos = (TypeExtractFileNameInfos *)GetProcAddress(hDll, "_ExtractFileNameInfos"); //check function address if(ExtractFileNameInfos != 0) { //call dll function ExtractFileNameInfos(cFileName, cData); } else { //function address error iReturn = -2; } } else { //dll handle error iReturn = -1; } //unload dll int test = FreeLibrary(hDll); DWORD dwLastError = GetLastError(); return iReturn; }Und zugehöriger Header:
typedef void TypeExtractFileNameInfos(char *cFileName, int *cData); int ExtractFileNameInfos(char *cFileName, int *cData); #define DLL_NAME "Analyse.dll"Aufruf der Schnittstellenfunktion:
void __fastcall TForm1::Button1Click(TObject *Sender) { struct FileNameInfos fni; int itest; ExtractFileNameInfos("C:\\Temp\\Protokollauswertung\\source_code\\_TestFiles\\HSP\\ES690.1_11_F_2006_02_06_15_43_02.hsp", &itest); Memo1->Lines->Add(fni.sProduct); Memo1->Lines->Add(fni.sSerialNumber); Memo1->Lines->Add(fni.sPassFail); Memo1->Lines->Add(fni.sDate); Memo1->Lines->Add(fni.sTime); Memo1->Lines->Add(fni.sFileExt); Memo1->Lines->Add(fni.sFabCode); }Dies ist momentan ein Testanwendung die eigentlich nichts anderes macht als die DLL Funktion aufzurufen.
MfG Stephan
-
Hallo
ich sehe jetzt keinen Fehler. nur eins verwundert mich schon
int ExtractFileNameInfos(char *cFileName, int *cData) { ... ExtractFileNameInfos = (TypeExtractFileNameInfos *)GetProcAddress(hDll, "_ExtractFileNameInfos"); }Du hast eine Funktionsimplementation, in der du dem Funktionssybol eine andere dynamische Adresse zuweist. Ob das wirklich erlaubt ist weiß ich nicht, aber es könnte schon eine ursache für seltsame Speicherfehler sein.
Natürlich ist dort lokal ein Funktionspointer mit gleichem Namen angelegt, aber das muß nicht viel heißen./Edit :; und du solltest die char*-Parameter noch als const dekalrieren, weil du ja String-Literale übergibst, die nicht veränert werden können/dürfen.
bis bald
akari
-
Hi
Du hast Recht, jedoch es hat leider keinen Einfluß ;-((
MfG Stephan
-
Hallo zusammen
Also wenn ich dies richtig sehe, ist dies ein Bug vom BCB / CodeGuard.
http://qc.borland.com/wc/qcmain.aspx?d=3919MfG Stephan