Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Malwieder von C nach Delphi (https://www.delphipraxis.net/84313-malwieder-von-c-nach-delphi.html)

yörsch 15. Jan 2007 10:17


Malwieder von C nach Delphi
 
HALLO Zusammen,

am folgenden CODE siz ich schon seit einpaar Tagen. :wall:
Vieleicht kann bin ich schon Blind vom lauter hingucken... oder seh den Wald vor lauter Bäumen nicht. :(
Code:
struct { 
   unsigned int iIdent;
   unsigned int iDataOffset;
   tBoImgCode   sDataCode;
   struct flag {
      unsigned fFlipVert: 1;
      unsigned fFlipHori: 1;
   } sFlags;
   unsigned int   aStamp[64];
} tBoImgDataInfoHeader, *tpBoImgDataInfoHeader;
...
DWORD WINAPI FX_GetImageData (  int iCamId, tpBoImgDataInfoHeader pImgHeader, PVOID pBuffer, int iBufferSize )
...
char * pBuffer = (char*) new char[ iSizeOfBufferToSupply ];
tBoImgDataInfoHeader ImgInfo;
...
memset( &ImgInfo, 0, sizeof(tBoImgDataInfoHeader));
FX_GetImageData(  iLabel, &ImgInfo, pBuffer, iSizeOfBufferToSupply );
Delphi-Quellcode:
tflagBoImgDataInfoHeader = packed Record
  fFlipVert : Boolean;
  fFlipHori : Boolean;
end;
tBoImgDataInfoHeader = packed Record
  iIdent : LongWord;   
  iDataOffset : LongWord;   
  sDataCode : tBoImgCode;
  flags : tflagBoImgDataInfoHeader;
  aStamp : array [0..63] of LongWord;
end;
tpBoImgDataInfoHeader = ^tBoImgDataInfoHeader;
...
FUNCTION FX_GetImageData ( iCamId : Integer; pImgHeader : tpBoImgDataInfoHeader; Buffer: Pointer; iBufferSize: Integer) :DWORD;FAR;STDCALL;External DLLFile;    
...
pBuffer   : array of ^CHAR   ;
SetLength(pBuffer,iSizeOfBufferToSupply );
FillMemory(@ImgInfo,SizeOf(ImgInfo),0);// memset
fReturn := FX_GetImageData(  iLabel, @ImgInfo, pBuffer, iSizeOfBufferToSupply );
Als Fehler bekomme ich beim schließen der DLL eine Zugriffsverletzung.
Gruß
Jörg

Muetze1 15. Jan 2007 10:37

Re: Malwieder von C nach Delphi
 
1. Möglichkeit mit Bitmaske
Delphi-Quellcode:
  TBoImgDataInfoHeader = Record
    iIdent: LongWord;
    iDataOffset: LongWord;
    sDataCode: TBoImgCode; // ??? Deklaration fehlt!
    sFlags: LongWord; // Bit 0: fFlipVert; Bit 1: fFlipHori
    aStamp: Array[0..63] of LongWord;
  End;
  PBoImgDataInfoHeader = ^TBoImgDataInfoHeader;
2. Möglichkeit mit Set Of, dabei weiss ich nicht, ob der Set sich hier auch auf 32 Bit breit macht oder vllt. kleiner ist, was fatal wäre...
Delphi-Quellcode:
  TBoImgDataFlipped = Set Of ( dfVertical, dfHorizontal );
  TBoImgDataInfoHeader = Record
    iIdent: LongWord;
    iDataOffset: LongWord;
    sDataCode: TBoImgCode; // ??? Deklaration fehlt!
    sFlags: TBoImgDataFlipped;
    aStamp: Array[0..63] of LongWord;
  End;
  PBoImgDataInfoHeader = ^TBoImgDataInfoHeader;
/EDIT: Und das nachfolgende korrigiert:

Delphi-Quellcode:
Var
  pBuffer: PByte;
...
  pBuffer := GetMem(iSizeOfBufferToSupply);
  Try
    FillChar(ImgInfo, SizeOf(ImgInfo), 0);// memset

    fReturn := FX_GetImageData(  iLabel, @ImgInfo, pBuffer, iSizeOfBufferToSupply );
  Finally
    FreeMem(pBuffer);
  End;

Der_Unwissende 15. Jan 2007 10:44

Re: Malwieder von C nach Delphi
 
Hi,
es gibt ein paar Kleinigkeiten, die Du ändern solltest. So ist int nur mindestens 32 Bit groß, sollte aber eigentlich auch in C immer der Standarddatentyp (Integer in Delphi) sein. unsigned und unsigned int solltest Du entsprechend durch Cardinal ersetzen.
Insbesondere gilt dies auch für fFlipVert und fFlipHori, bei den beiden handelt es sich um einen gemeinsamen Datentypen. Du hast also ein Cardinal, das ausreichebd groß ist um beide Variablen zu speichern. Für diese Struktur wird aber wirklich ein komplettes Cardinal verlangt.

Ich denke besser kommst Du hin mit:

Delphi-Quellcode:
type
  TFlag = record
    fFlipVert: Boolean;
    fFlipHori: Boolean;
  end;

  TBoImgDataInfoHeaderFlag = record
    case Integer of
      1: (flag: TFlag);
      2: (c: Cardinal);
  end;

  PBoImgDataInfoHeader = ^TBoImgDataInfoHeader;
  TBoImgDataInfoHeader = record
    iIdent: Cardinal;
    iDataOffset: Cardinal;
    sFlags: TBoImgDataInfoHeaderFlag;
    aStamp: Array[0..63] of Cardinal;
  end;
Hoffe ich lieg jetzt nicht auch völlig daneben.

Was deinen Fehler/Code angeht, Du weißt, dass Du in PBuffer ein Array von Zeigern erzeugst? Die Zeiger sind aber nicht initialisiert. Was genau wird denn im C-Programm hier übergeben? Da es sich um einen Puffer handelt und es offensichtlich um ein Bild geht, solltest du vielleicht einfach ein Array of Byte verwenden (Der Datentyp Char in C entspricht auch dem Byte in Delphi). In C wirst Du statt einem Array von Bytes i.d.R. eher etwas wie (Char* buffer, int bufferSize) finden. Also die Größe wird immer getrennt gespeichert (und gehört nicht direkt zum Array!). C Arrays sind nur Zeiger auf das erste Element und Du springst einfach im Speicher weiter. Du musst dabei selbst schauen, dass Du die Grenzen des Arrays nicht verletzt!

Gruß Der Unwissende

Muetze1 15. Jan 2007 11:20

Re: Malwieder von C nach Delphi
 
Dein TFlag wird aber 64 Bit gross, da du 2x Boolean als grössten Typ hast, wobei jeder Boolean mit 32 Bit zu Buche schlägt. Damit wäre dein Case mit dem Cardinal auch 64 Bit groß.

Die Original C Struktur hat dort Bits definiert, somit scheiden Boolean (egal welcher Typ, ob ByteBool, WordBool, etc) aus.

Der_Unwissende 15. Jan 2007 11:23

Re: Malwieder von C nach Delphi
 
Sorry, seh' gerade erst, dass ich deinen Beitrag völlig übersehen hab, der war nicht da als ich anfing zu tippen und roten Kasten habe ich nicht gesehen (muss wohl doch mal zum Optiker).

Dachte, dass ein Boolean nur ein Byte einnimmt, hm, sizeOf gibt mir da sogar recht (oder ich mach nur was falsch), aber dein Weg ist definitiv sauberer und besser (war mir nicht mehr sicher ob man die Anzahl der Bits oder Byte angibt (in C)).

Gruß Der Unwissende

Muetze1 15. Jan 2007 11:25

Re: Malwieder von C nach Delphi
 
Zitat:

Zitat von Der_Unwissende
Dachte, dass ein Boolean nur ein Byte einnimmt, hm, sizeOf gibt mir da sogar recht (oder ich mach nur was falsch), ...

Auch in einem nicht "packed" Record? Dort sollte er im Normalfall auf 32 Bit erweitert werden.

yörsch 15. Jan 2007 11:58

Re: Malwieder von C nach Delphi
 
der vollständigkeithalber
Code:
typedef struct _BOIMGCODING {
  eBOIMGCODEINF   iCode;
  int      iCanalBytes;
  int            iCanalBits;   
  int      iCanals;
  int      iPlanes;
#ifndef __BORLANDC_
  inline int            operator ==(const _BOIMGCODING& code );
  inline int            operator ==(const _BOIMGCODING* code );
#endif
} tBoImgCode, *tpBoImgCode;
da kein BORLANDC
Delphi-Quellcode:
 tBoImgCode = packed record
   iCode       : Integer;
   iCanalBytes : Integer;
   iCanalBits  : Integer;
   iCanals     : Integer;
   iPlanes     : Integer;
end;

yörsch 15. Jan 2007 12:18

Re: Malwieder von C nach Delphi
 
FillChar(ImgInfo, SizeOf(ImgInfo), 0);

FillMemory(@ImgInfo,SizeOf(ImgInfo),0);

machen bei meinem Problem und im Debugger keinen Unterschied

Auch die verschiedenen Varianten der Struktur machen keinen Unterschied :witch:

Muetze1 15. Jan 2007 12:36

Re: Malwieder von C nach Delphi
 
Zitat:

Zitat von yörsch
da kein BORLANDC

Wüsste auch nicht, wie du Operatoren definieren solltest...

Zitat:

Zitat von yörsch
FillChar(ImgInfo, SizeOf(ImgInfo), 0);

FillMemory(@ImgInfo,SizeOf(ImgInfo),0);

machen bei meinem Problem und im Debugger keinen Unterschied

Mag sein, aber ich habe die Parameter von FillMemory() nicht im Kopf, von FillChar() aber schon. Und da ich bei der Variante 100%ig richtig liege, hatte ich diese gepostet.

yörsch 16. Jan 2007 10:37

Re: Malwieder von C nach Delphi
 
DICKES DANKE :love:

ohne eure anregung währe ich nicht weiter gekommen ! :hello: :party:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:54 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