Sporadische Zugriffsverletzung beim Aufruf einer C++ Dll aus Delphi
-
Hallo Leute,
ich habe ein kleines Problem mit einer C++ Dll, die ich aus einem Delphi-Programm aufrufe.
Die wahrscheinlich fehlerhafte Funktion bekommt als Parameter eine Liste von Dokumenten, die dann bearbeitet werden. Bei einem Testrechner erscheint dann folgende Fehlermeldung (Auf 5 anderen Rechnern läuft das Programm ohne Probleme):Exception EAccessViolation in Modul MeineDelphiExe.exe bei 00002151. Zugriffsverletzung bei Adresse 00402151 in Modul 'MeineDelphiExe.exe'. Schreiben von Adresse 00000000
Die Fehlermeldung kommt aber erst wenn ich das Formular schließe (MDI-Form). Die DLL wird zu diesem Zeitpunkt noch nicht freigegeben.
Ich bin mit C++ noch nicht wirklich bewandert. Sieht Jemand von euch was ich hier falsch mache, oder habt Ihr eine Idee was ich mir noch näher anschauen sollte? (Ich habe den Code etwas abgekürzt).
type TDOCUMENTDATA = record SPathSource : PCHar; SPfadZiel : PChar; ISigned : Integer; end; type AssignDocuments = function( var fArrDocDate : Array of TDOCUMENTDATA; inIDocCount : Integer) : Integer; cdecl;
Hier die DLL-Funktion. Kann es sein, das ich hier Arbeitsspeicher meines Delphi-Programms überschreibt?!?
extern "C" __declspec(dllexport)int AssignDocuments(DOCUMENTDATA inArrFilenames[], int inIDocCount); int AssignDocuments(DOCUMENTDATA inArrFilenames[], int inIDocCount) { int ret = OK; int const lIDOCCOUNT = inIDocCount; unsigned char * contentBuffer; size_t filePos; DOCUMENT* documents = new DOCUMENT[lIDOCCOUNT+1]; for (int i=0; i<lIDOCCOUNT; i++) { inArrFilenames[i].BSigned = 0; struct _stat buf; result = _stat(inArrFilenames[i].SPathSource, &buf ); CONTENT_BUF_LEN = buf.st_size; contentBuffer = (unsigned char*)malloc(CONTENT_BUF_LEN); if (NULL == contentBuffer) { return 16; } int fd; int openRet = _sopen_s(&fd, inArrFilenames[i].SPathSource, O_RDONLY | O_BINARY, _SH_DENYWR, S_IREAD); if (0 != openRet) { return 17; } filePos = 0; while (true) { int bytesRead = _read(fd, &contentBuffer[filePos], CONTENT_BUF_LEN-filePos); if (bytesRead < 0) { return 18; } if (bytesRead == 0) { break; } filePos+=bytesRead; } _close(fd); if (NULL == signatureBuffer) { return 19; } //document struct documents[i].version = 7; documents[i].documentFileName = inArrFilenames[i].SPathSource; documents[i].dataToBeSigned = contentBuffer; documents[i].dataToBeSignedLen = filePos; documents[i].documentType = DATATYPE_PDF; } ret = signDocs(documents, lIDOCCOUNT, cipherCerts, cipherCertCount, softKeyData, softKeyDataCount); //Funktion aus einer anderen DLL if (ret == OK) { for (int j=0; j<lIDOCCOUNT; j++) { int fd = 0; int openRet; if ((NULL == inArrFilenames[j].SPfadZiel) || (*inArrFilenames[j].SPfadZiel == '\0')) { char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath_s(inArrFilenames[j].SPathSource, drive, dir, fname, ext); char path[255]; sprintf_s(path, 255, "%s%s%s_NEW%s", drive, dir, fname, ext); openRet = _sopen_s(&fd, path, O_CREAT | O_WRONLY | O_BINARY, _SH_DENYRW, S_IREAD | _S_IWRITE); inArrFilenames[j].SPfadZiel = path; } else { openRet = _sopen_s(&fd, inArrFilenames[j].SPfadZiel, O_CREAT | O_WRONLY | O_BINARY, _SH_DENYRW, S_IREAD | _S_IWRITE); } if (0 == openRet) { inArrFilenames[j].BSigned = 1; _write(fd, documents[j].attachment, documents[j].attachmentLength); _close(fd); } } } for (int d=0; d<lIDOCCOUNT; d++) { if (documents[d].signature != NULL) { free (documents[d].signature); documents[d].signature = NULL; } } delete[] documents; documents = NULL; return ret; }