AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

C++ zu Delphi funktion umschreiben

Ein Thema von XXcD · begonnen am 5. Okt 2010 · letzter Beitrag vom 6. Okt 2010
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von XXcD
XXcD

Registriert seit: 19. Sep 2006
581 Beiträge
 
Delphi 2007 Professional
 
#1

C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 18:44
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:
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;

}
Ich hoffe mir kann dabei jemand helfen.
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 22:13
Guten Abend,

ein Versuch:

Delphi-Quellcode:
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 = 'TITLEthen
           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;
Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 22:17
Du kopierst einfach den gesamten Dateiinhalt in "mem" rein und läßt dann folgendes drüberlaufen
Delphi-Quellcode:
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
hab auch glaich mal das Unicodeproblemchen der API angepaßt
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:
- für den Resourcenschutzblock
- und unbedingt S: AnsiString , da er D2009 nutzt und das Unicode hier bestimmt negative Auswirkungen zeigt
- 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
$2B or not $2B

Geändert von himitsu ( 5. Okt 2010 um 22:28 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von XXcD
XXcD

Registriert seit: 19. Sep 2006
581 Beiträge
 
Delphi 2007 Professional
 
#4

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 22:49
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.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 22:51
Beim ausführen bekomme ich immer ein Access Violation.
Und wo?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von XXcD
XXcD

Registriert seit: 19. Sep 2006
581 Beiträge
 
Delphi 2007 Professional
 
#6

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 22:53
An dieser Stelle:

str := mem[8] or (mem[9] shl 8);
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 23:15
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 23:15
Man sollte vorher Speicher für das Array reservieren:

SetLength(mem,2048); Und das Einlesen muss so aussehen:

stream.read(mem[0],2048);
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von XXcD
XXcD

Registriert seit: 19. Sep 2006
581 Beiträge
 
Delphi 2007 Professional
 
#9

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 23:22
Ok das funktioniert.
Vielen Dank schonmal, nur wird der Titel nicht komplett ausgelesen, da stehen dann nur die ersten 4 Buchstaben.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

AW: C++ zu Delphi funktion umschreiben

  Alt 5. Okt 2010, 23:42
Vielen Dank schonmal, nur wird der Titel nicht komplett ausgelesen, da stehen dann nur die ersten 4 Buchstaben.
Sizeof(mem) = 4 ... also 4 Byte/Zeichen

stattdessen mal lstrlen(PAnsiChar(@mem[pos])) versuchen
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz