![]() |
C++ zu Delphi funktion umschreiben
Hallo,
ich habe eine C++ Funktion zum auslesen eines Titels in einer Datei. Diese müsste ich in Delphi übernehmen, nur komme ich dabei nicht wirklich weiter. Da ich leider keine Ahnung von C++ habe, bringt mich das zum verzweifeln. Hier ist mal der Code:
Code:
Ich hoffe mir kann dabei jemand helfen.
int parse_cuv(char * file, char *title_name)
{ FILE *fp; fp = fopen(file, "rb"); if (fp != NULL) { unsigned len, pos, str; unsigned char *mem=NULL; fseek(fp, 0, SEEK_END); len=ftell(fp); mem= (unsigned char *) malloc(len+16); if(!mem) {fclose(fp);return -2;} memset(mem, 0, len+16); fseek(fp, 0, SEEK_SET); fread((void *) mem,len, 1, fp); fclose(fp); str= (mem[8]+(mem[9]<<8)); pos=(mem[0xc]+(mem[0xd]<<8)); int indx=0; while(str<len) { if(mem[str]==0) break; if(!strcmp((char *) &mem[str], "TITLE")) { strncpy(title_name, (char *) &mem[pos], 63); free(mem); return 0; } while(mem[str]) str++;str++; pos+=(mem[0x1c+indx]+(mem[0x1d+indx]<<8)); indx+=16; } if(mem) free(mem); } return -1; } |
AW: C++ zu Delphi funktion umschreiben
Guten Abend,
ein Versuch:
Delphi-Quellcode:
Grüße
function parse_cuv(fileName: AnsiString; var titleName: AnsiString):Byte;
var fp : TMemoryStream; i : Integer; str : smallInt; pos : smallInt; value : smallInt; idx : Integer; s : String; begin fp := TMemoryStream.Create; try fp.LoadFromFile(fileName); fp.Seek(8,soFromBeginning); fp.Read(str,2); // todo swapBytes(str) fp.Seek($c,soFromBeginning); fp.Read(pos,2); // todo swapBytes(pos) idx := 0; while str < fp.size do begin fp.Seek(str,soFromBeginning); setLength(s,length('TITLE')); fp.Read(s,length('TITLE')); if s = 'TITLE' then begin setLength(titleName,63); fp.Read(titleName,63); result := 0; break; end; // keine Ahnung was das mir sagen soll. //while(mem[str]) str++;str++; fp.Seek($1c+idx,soFromBeginning); fp.Read(value,2); // todo swapBytes(value) pos := pos + value; inc(idx,16); end; finally fp.free; end; end; Klaus |
AW: C++ zu Delphi funktion umschreiben
Du kopierst einfach den gesamten Dateiinhalt in "mem" rein und läßt dann folgendes drüberlaufen
Delphi-Quellcode:
hab auch glaich mal das Unicodeproblemchen der API angepaßt
var mem: TByteDynArray;
title_name: AnsiString "sonstiges": Integer; str := mem[8] or (mem[9] shl 8); pos := mem[12] or (mem[13] shl 8); indx := 0; title_name := ''; while str < Length(mem) do begin if mem[str] = 0 then break; if not lstrcmpA(@mem[str], 'TITLE') then begin SetString(title_name, PAnsiChar(@mem[pos])); //title_name := Copy(title_name, 1, 63); break; end; while mem[str] <> 0 do inc(str); inc(str); inc(pos, mem[28 + indx] or (mem[29 + indx] shl 8)); inc(indx, 16); end; // Ergebnis: title_name und über das TByteDynArray wurde auch gleich der fehlende Resourcen-Schutzblock kompensiert (das "mem" im C-Code ist ein Pointer, dessen Speicherfreigabe nicht sichergestellt war). @Klaus01: - :thumb: für den Resourcenschutzblock - und unbedingt
Delphi-Quellcode:
, da er D2009 nutzt und das Unicode hier bestimmt negative Auswirkungen zeigt
S: AnsiString
- da, wo du keine Ahnung hast ... den letzen Befehl in eine neue Zeile und schon wird es verständlicher (Werte/Integer/Bytes in IFs werden als "Boolean" angesehn ... <> 0) - ich glaub swapBytes ist nicht nötig (Low, High) - statt SmallInt lieber Word verwenden ... nicht daß man hier eventuell noch in eine Endlosschleife tappt |
AW: C++ zu Delphi funktion umschreiben
Also ich bekomme den Code noch nicht so ganz zum laufen.
Beim ausführen bekomme ich immer ein Access Violation.
Delphi-Quellcode:
var
stream : TFileStream; mem: TByteDynArray; title_name: AnsiString; indx: integer; str: word; pos : word; begin stream := TFileStream.Create(Files,fmOpenRead); stream.read(mem,2048); str := mem[8] or (mem[9] shl 8); pos := mem[12] or (mem[13] shl 8); indx := 0; title_name := ''; while str < Length(mem) do begin if mem[str] = 0 then break; if not lstrcmpA(@mem[str], 'TITLE') = 0 then begin SetString(title_name, PAnsiChar(@mem[pos]), Sizeof(mem)); //title_name := Copy(title_name, 1, 63); break; end; while mem[str] <> 0 do inc(str); inc(str); inc(pos, mem[28 + indx] or (mem[29 + indx] shl 8)); inc(indx, 16); end; end; Edit: Ich nutze Delphi 2007, hatte nen paar Probleme mit OpenGL in der 2009 Version. |
AW: C++ zu Delphi funktion umschreiben
Zitat:
|
AW: C++ zu Delphi funktion umschreiben
An dieser Stelle:
Delphi-Quellcode:
str := mem[8] or (mem[9] shl 8);
|
AW: C++ zu Delphi funktion umschreiben
Ist die Datei auch 2048 Byte groß?
Und es wäre nicht schlecht, wenn man "mem" etwas Speicher gibt (SetLength), bevor man da versucht war reinzuspeichern (read). (Wobei ich hier des Zugriffsverletzung schon beim read erwartet hätte.) Wegen D2009/D2007 ... da die Datei so oder so Ansi ist, sollte man den Code dennoch auf AnsiString auslegen. Denn sonst gibt es mal Probleme, wenn sich doch irgendwann mal überlegt dieses auf D2009+ zu portieren. |
AW: C++ zu Delphi funktion umschreiben
Man sollte vorher Speicher für das Array reservieren:
Delphi-Quellcode:
Und das Einlesen muss so aussehen:
SetLength(mem,2048);
Delphi-Quellcode:
stream.read(mem[0],2048);
|
AW: C++ zu Delphi funktion umschreiben
Ok das funktioniert.
Vielen Dank schonmal, nur wird der Titel nicht komplett ausgelesen, da stehen dann nur die ersten 4 Buchstaben. |
AW: C++ zu Delphi funktion umschreiben
Zitat:
stattdessen mal
Delphi-Quellcode:
versuchen
lstrlen(PAnsiChar(@mem[pos]))
oder diesen Parameter weglassen (ich dachte so würde SetString bis zur #0 lesen) oder doch mal 63 dort versuchen, aber ich bin mir nicht sicher, ob SetString dann auch bei der #0 aufhört. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz