Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Array of Integer und crash (https://www.delphipraxis.net/192085-array-integer-und-crash.html)

EWeiss 19. Mär 2017 07:37

Array of Integer und crash
 
Ich hab ein Array of Integer in einer Procedure definiert.

Delphi-Quellcode:
type
  TOutFrameDelay = array of Integer;
  POutFrameDelay = ^TOutFrameDelay;
....
procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: UINT;
  var OutFrameDelay: TOutFrameDelay);
wenn ich nun das Array redimensioniere dann kracht es mal wieder.

Delphi-Quellcode:
SetLength(OutFrameDelay, InFrameCount - 1);


SetLength müsste so doch auch mit Integer funktionieren oder nicht?
Was läuft hier wieder schief? LOL

Bin wieder mal die ganze Nacht wach wird zeit für's Bett.. hehehehehee

gruss

haentschman 19. Mär 2017 07:44

AW: Array of Integer und crash
 
Moin...8-)

Was spricht gegen TList<Integer>. Da hast du das Pointer geschubse nicht. :wink:

EWeiss 19. Mär 2017 07:46

AW: Array of Integer und crash
 
Zitat:

Zitat von haentschman (Beitrag 1364688)
Moin...8-)

Was spricht gegen TList<Integer>. Da hast du das Pointer geschubse nicht. :wink:

Wie meinst das?
Eigentlich müsste das doch funktionieren frage mich nur warum nicht.

gruss

Uwe Raabe 19. Mär 2017 08:10

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364687)
procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: Integer;
var OutFrameDelay: TOutFrameDelay);[/DELPHI]

Liegt vielleicht daran, was dieser procedure übergeben wird?

EWeiss 19. Mär 2017 08:19

AW: Array of Integer und crash
 
Delphi-Quellcode:
var OutFrameDelay: TOutFrameDelay
Habe gelesen das man hier den var Parameter übergeben soll wenn eine Type Deklaration für das Array angelegt wurde.

Aber auch wenn ich diesen entferne kracht es.
Was anderes fällt mir da jetzt nicht ein.

Das Image ist korrekt, der FrameConter ist 14 also auch korrekt.
Übrig bleibt dann nur das OutFrameDelay.

gruss

haentschman 19. Mär 2017 08:25

AW: Array of Integer und crash
 
Zitat:

Wie meinst das?
:wink: damit wärst du schon fertig ohne die Pointer Problematik und Arrays als Parameter.

EWeiss 19. Mär 2017 08:33

AW: Array of Integer und crash
 
Zitat:

Zitat von haentschman (Beitrag 1364693)
Zitat:

Wie meinst das?
:wink: damit wärst du schon fertig ohne die Pointer Problematik und Arrays als Parameter.

Ich habe kein Problem mit dem Pointern nur mit dem Array.

Delphi-Quellcode:
procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: UINT;
  var OutFrameDelay: TOutFrameDelay);
Delphi-Quellcode:
procedure LoadGif;
var
  FrameCount: UINT;
  FrameDelay: TOutFrameDelay;
begin

  FrameCount := 0;

  if GetGifFrameCount(gp.GifImage, @GuidFDT, FrameCount) = S_OK then
    If (FrameCount - 1) = 0 then
    begin
      SetLength(FrameDelay, 0);
    end else
    begin
      GetGifFrameDelays(gp.GifImage, FrameCount, FrameDelay);
    end;
end;
Jetzt brat mir einer nen Storch warum geht das nicht.

grrrr... LOL

gruss

Uwe Raabe 19. Mär 2017 09:32

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364694)
Jetzt brat mir einer nen Storch warum geht das nicht.

Funktioniert doch! Mangels weiterer Informationen habe ich das mal auf ein Minimum runter gebrochen:

Delphi-Quellcode:
program Project219;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TOutFrameDelay = array of Integer;

procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: Cardinal;
  var OutFrameDelay: TOutFrameDelay);
begin
  SetLength(OutFrameDelay, InFrameCount - 1);
end;

procedure Main;
var
  FrameCount: Cardinal;
  FrameDelay: TOutFrameDelay;
begin

  FrameCount := 4;

//  if GetGifFrameCount(gp.GifImage, @GuidFDT, FrameCount) = S_OK then
    If (FrameCount - 1) = 0 then
    begin
      SetLength(FrameDelay, 0);
    end else
    begin
      GetGifFrameDelays(0, FrameCount, FrameDelay);
    end;

  Writeln('OK');
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

p80286 19. Mär 2017 09:42

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364694)
Ich habe kein Problem mit dem Pointern nur mit dem Array.

Sicher?
der Pointer muß auf Myarray[0] zeigen.

(ich hab jedenfalls keine Zuweisung gesehen?)

Gruß
K-H

EWeiss 19. Mär 2017 13:54

AW: Array of Integer und crash
 
Dank euch muss mir das nochmal ansehen.
Bin jetzt wieder dabei. ;)

Delphi-Quellcode:
der Pointer muß auf Myarray[0] zeigen.
Wie ? Wenn ich das Array vorher nicht dimensionieren kann.
Es ist ja dann noch nicht mal initialisiert ohne SetLength.

gruss

Uwe Raabe 19. Mär 2017 14:26

AW: Array of Integer und crash
 
Delphi-Quellcode:
type
  TOutFrameDelay = array of Integer;
  POutFrameDelay = ^TOutFrameDelay;
Das mit dem Pointer-Typ habe ich auch nicht verstanden. Ein dynamisches Array ist doch intern eh schon ein Pointer auf das eigentliche Array (ähnlich wie bei class), welcher mit SetLength gesetzt wird. Durch die Deklaration als var-Parameter funktioniert dies ja auch wie erwartet. Solche Deklarations-Paare wie diese kennen ich eigentlich nur noch aus Zeiten vor Einführung dynamischer Arrays.

EWeiss 19. Mär 2017 14:36

AW: Array of Integer und crash
 
ok das war ein versuch da es nicht lief.
Dann kann ich mir das ja schenken ;)

Delphi-Quellcode:
POutFrameDelay = ^TOutFrameDelay;


gruss

EWeiss 19. Mär 2017 15:35

AW: Array of Integer und crash
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1364697)
Zitat:

Zitat von EWeiss (Beitrag 1364694)
Jetzt brat mir einer nen Storch warum geht das nicht.

Funktioniert doch! Mangels weiterer Informationen habe ich das mal auf ein Minimum runter gebrochen:

Delphi-Quellcode:
program Project219;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TOutFrameDelay = array of Integer;

procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: Cardinal;
  var OutFrameDelay: TOutFrameDelay);
begin
  SetLength(OutFrameDelay, InFrameCount - 1);
end;

procedure Main;
var
  FrameCount: Cardinal;
  FrameDelay: TOutFrameDelay;
begin

  FrameCount := 4;

//  if GetGifFrameCount(gp.GifImage, @GuidFDT, FrameCount) = S_OK then
    If (FrameCount - 1) = 0 then
    begin
      SetLength(FrameDelay, 0);
    end else
    begin
      GetGifFrameDelays(0, FrameCount, FrameDelay);
    end;

  Writeln('OK');
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

JO läuft bei mir auch wenn ich anstelle vom realen Image eine 0 angebe.
Hmm.. :wall:


gruss

Uwe Raabe 19. Mär 2017 15:38

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364748)
JO läuft bei mir auch wenn ich anstelle vom realen Image eine 0 angebe.

Dann liegt der Fehler aber nicht beim
Delphi-Quellcode:
SetLength
, sondern an irgendeiner anderen Stelle mit Bezug auf
Delphi-Quellcode:
InGifImage
.

EWeiss 19. Mär 2017 15:43

AW: Array of Integer und crash
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1364749)
Zitat:

Zitat von EWeiss (Beitrag 1364748)
JO läuft bei mir auch wenn ich anstelle vom realen Image eine 0 angebe.

Dann liegt der Fehler aber nicht beim
Delphi-Quellcode:
SetLength
, sondern an irgendeiner anderen Stelle mit Bezug auf
Delphi-Quellcode:
InGifImage
.

Scheint so nur das Problem ist alle GDIPlus aufrufe geben mir ein S_OK zurück.
Wo soll dann was falsch sein wenn der Compiler mir true zurück gibt.
Ich denke das muss ich selber suchen/Fixen.

Danke

gruss

EWeiss 19. Mär 2017 16:20

AW: Array of Integer und crash
 
Nach dem Aufruf

Delphi-Quellcode:
if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
begin
Delphi-Quellcode:
function GetPropertyItem(InGifImage: Cardinal; PropertyID: ULONG; PropertyItemSize: UINT;
  var PropertyItemData: TPropertyItem): integer;
begin
  // Daten auslesen
  Result := GDIP_GetPropertyItem(InGifImage, PropertyID, PropertyItemSize, @PropertyItemData);

end;
nach begin..
gibt mir InGifImage und PropSize den wert 8 zurück das kann nicht stimmen.

Warum werden die Wert verändert.
Delphi-Quellcode:
Result := GDIP_GetPropertyItem(InGifImage, PropertyID, PropertyItemSize, @PropertyItemData);


gibt 0 zurück aber in der nächsten Funktion verliert InGifImage dne vorher übergebenen Wert.

gruss

Uwe Raabe 19. Mär 2017 17:51

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364757)
Warum werden die Wert verändert.

Das lässt sich anhand dieser kurzen Code-Fragmente nicht erkennen.

EWeiss 19. Mär 2017 18:47

AW: Array of Integer und crash
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1364763)
Zitat:

Zitat von EWeiss (Beitrag 1364757)
Warum werden die Wert verändert.

Das lässt sich anhand dieser kurzen Code-Fragmente nicht erkennen.

Ok dann fange ich mal an.

Delphi-Quellcode:
type
  PropertyTagType = (
    PropertyTagTypeByte = 1,
    PropertyTagTypeASCII = 2,
    PropertyTagTypeShort = 3,
    PropertyTagTypeLong = 4,
    PropertyTagTypeRational = 5,
    PropertyTagTypeUndefined = 7,
    PropertyTagTypeSLong = 9,
    PropertyTagTypeSRational = 10
  );
  TPropertyTagType = PropertyTagType;

  PropertyItem = record
    id      : PROPID;
    length  : ULONG;
    type_    : TPropertyTagType;
    value   : Pointer;
  end;
  TPropertyItem = PropertyItem;
  PPropertyItem = ^TPropertyItem;

const
  PropertyTagFrameDelay: ULONG = $5100;
  FrameDimensionTime: TGUID = '{6aedbd6d-3fb5-418a-83a6-7f45229dc872}';

// Start! 
//#######################################
AnimateGif := TAnimateGif.Create(nil);

constructor TAnimateGif.Create(AOwner: TComponent);
begin

  LoadGif;
end;

procedure TAnimateGif.LoadGif;
var
  FrameCount: UINT;
  FrameDelay: TOutFrameDelay;
begin

  FrameCount := 0;

  if GetGifFrameCount(gp.GifImage, FrameCount) = S_OK then
  begin
    If (FrameCount - 1) = 0 then
    begin
      SetLength(FrameDelay, 0);
    end
    else
    begin
      GetGifFrameDelays(gp.GifImage, FrameCount, FrameDelay);
    end;
  end;
end;

function TAnimateGif.GetGifFrameCount(GifImage: Cardinal; var OutFrameCount: UINT): integer;
begin

  Result := GDIP_ImageGetFrameCount(GifImage, @FrameDimensionTime, OutFrameCount);
end;

procedure TAnimateGif.GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: UINT;
  var OutFrameDelay: TOutFrameDelay);
var
  PROP: TProp;
  PropCount: integer;
  Size: integer;
  PropSize: UINT;
  PropItem: TPropertyItem;
begin

  Size := 0;

  // Datengröße vom EXIF-Tag
  // "PropertyTagFrameDelay" ermitteln
  if GDIP_GetPropertyItemSize(InGifImage, PropertyTagFrameDelay, PropSize) = S_OK then
  begin
    // Daten auslesen
    if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
    begin
      // PropertyTyp ermitteln
      case PropItem.type_ of
        PropertyTagTypeByte:
          Size := 1;

        PropertyTagTypeShort:
          Size := 2;

        PropertyTagTypeLong:
          Size := 4;
      end;

      // Array zur Aufnahme der
      // Pausenzeiten dimensionieren
      SetLength(OutFrameDelay, (InFrameCount - 1));
    end;
  end;
end;

function TAnimateGif.GetPropertyItem(InGifImage: Cardinal; PropertyID: ULONG;
  PropertyItemSize: UINT; var PropertyItemData: TPropertyItem): integer;
begin

  // Daten auslesen
  Result := GDIP_GetPropertyItem(InGifImage, PropertyID, PropertyItemSize, @PropertyItemData);
end;

// API
//#######################################
function GDIP_GetPropertyItem(image: Cardinal; propId: PROPID; propSize: UINT;
  buffer: PPROPERTYITEM): integer; stdcall; external dllfile;


function GDIP_GetPropertyItem(Img: Cardinal; propId: PROPID; propSize: UINT;
  var buffer: PPROPERTYITEM): GPSTATUS; stdcall;
begin

  result := GdipGetPropertyItem(Img, propId, propSize, buffer);
end;

function GdipGetPropertyItem(
  image: Cardinal;
  propId: PROPID;
  propSize: UINT;
  var buffer: PPROPERTYITEM
): GPSTATUS; stdcall; external LibGdiPlus;
So das war's.
nachdem die Rückgabe erfolgt ist, in
Delphi-Quellcode:
TAnimateGif.GetGifFrameDelays
nach begin

Delphi-Quellcode:
if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
begin
Verändert sich der wert von InGifImage und PropSize beide haben dann den Wert 8.

Hier kracht es dann
Delphi-Quellcode:
SetLength(OutFrameDelay, (InFrameCount - 1));


gruss

Uwe Raabe 19. Mär 2017 21:00

AW: Array of Integer und crash
 
In der Doku zu GdipGetPropertyItem steht:
Zitat:

Before you call Image::GetPropertyItem, you must allocate a buffer large enough to receive that object — the size varies according to data type and value of the property item.
Diesen Schritt finde ich in deinem Code aber nicht:
Delphi-Quellcode:
  // Datengröße vom EXIF-Tag
  // "PropertyTagFrameDelay" ermitteln
  if GDIP_GetPropertyItemSize(InGifImage, PropertyTagFrameDelay, PropSize) = S_OK then
  begin
    // Daten auslesen
    if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
    begin
In der Folge ist der bereitgestellte Speicher für PropItem höchstwahrscheinlich nicht ausreichend und es werden wohl unkontrolliert andere Variablen überschrieben.

EWeiss 19. Mär 2017 21:06

AW: Array of Integer und crash
 
Die frage die da wäre welchen Buffer?

gruss

Zacherl 19. Mär 2017 21:08

AW: Array of Integer und crash
 
Delphi-Quellcode:
PropItem

EWeiss 19. Mär 2017 21:16

AW: Array of Integer und crash
 
Zitat:

Zitat von Zacherl (Beitrag 1364779)
Delphi-Quellcode:
PropItem

Delphi-Quellcode:
  PropertyItem = record
    id      : PROPID;
    length  : ULONG;
    type_    : TPropertyTagType;
    value   : Pointer;
  end;
  TPropertyItem = PropertyItem;
  PPropertyItem = ^TPropertyItem;

PropItem: TPropertyItem;
Was für einen buffer soll ich da allokieren ?
Die größe bzw. der Inhalt wird doch von der GdipGetPropertyItem zurück gegeben.

gruss

EWeiss 19. Mär 2017 21:27

AW: Array of Integer und crash
 
Ich habe den Fehler ??? gefunden.
In wie weit das ein fehler ist könnte mir mal bitte jemand erklären.

Wenn man jetzt hier schaut

Delphi-Quellcode:
procedure TAnimateGif.GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: UINT;
   var OutFrameDelay: TOutFrameDelay);
var
   PROP: TProp;
   PropCount: integer;
   Size: integer;
   PropSize: UINT;
   PropItem: TPropertyItem;
begin

   Size := 0;

   // Datengröße vom EXIF-Tag
   // "PropertyTagFrameDelay" ermitteln
   if GDIP_GetPropertyItemSize(InGifImage, PropertyTagFrameDelay, PropSize) = S_OK then
   begin
     // Daten auslesen
     if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
     begin
       // PropertyTyp ermitteln
       case PropItem.type_ of
         PropertyTagTypeByte:
           Size := 1;

         PropertyTagTypeShort:
           Size := 2;

         PropertyTagTypeLong:
           Size := 4;
       end;

       // Array zur Aufnahme der
       // Pausenzeiten dimensionieren
       SetLength(OutFrameDelay, (InFrameCount - 1));
     end;
   end;
end;
kann man sehen das ich das PropItem hier deklariert habe.

Delphi-Quellcode:
PropItem: TPropertyItem;


Diese habe ich nun herausgenommen und in meine Classe gesteckt.

Delphi-Quellcode:
  TAnimateGif = class(TComponent)
  private
    FSelectedIndex: Integer;
    PropItem: TPropertyItem;
Jetzt sag mir mal jemand warum das so ein Problem verursacht hat das es nach
Delphi-Quellcode:
    if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
    begin
jedes Mal gekracht hat und alle Variablen sich verändert haben.

gruss

Uwe Raabe 19. Mär 2017 21:31

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364781)
Was für einen buffer soll ich da allokieren ?
Die größe bzw. der Inhalt wird doch von der GdipGetPropertyItem zurück gegeben.

Schon, die Größe des Bereichs für das PropertyItem wird aber über GdipGetPropertyItemSize ermittelt.

Wenn der Speicherbereich für PropertyItem eh durch die Deklaration vorgegeben ist, warum dann die Abfrage über GDIP_GetPropertyItemSize? Kannst du mal prüfen, ob das wirklich den erwarteten Wert zurückgibt?

Delphi-Quellcode:
  if GDIP_GetPropertyItemSize(InGifImage, PropertyTagFrameDelay, PropSize) = S_OK then
  begin
    if PropSize <> Sizeof(PropItem) then
      { hier stimmt was nicht! }
    // Daten auslesen
    if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
Was deinen Fix angeht: ich fürchte, du hast immer noch den Fehler drin, er äußert sich jetzt vermutlich nur anders weil andere Variablen überschrieben werden. Hier gilt immer noch die goldene Regel: Wenn du nicht verstehst, warum eine Änderung den Fehler behebt, dann hast du ihn wahrscheinlich auch nicht behoben.

EWeiss 19. Mär 2017 21:37

AW: Array of Integer und crash
 
Zitat:

Was deinen Fix angeht: ich fürchte, du hast immer noch den Fehler drin, er äußert sich jetzt vermutlich nur anders weil andere Variablen überschrieben werden. Hier gilt immer noch die goldene Regel: Wenn du nicht verstehst, warum eine Änderung den Fehler behebt, dann hast du ihn wahrscheinlich auch nicht behoben.
Möglich da ich wirklich nicht weiß warum dieser das Problem behoben hat.
Ich denke mal das er einfach global deklariert werden muss damit die Daten nicht überschrieben werden.

Ich habe das geprüft und die Daten kommen alle richtig an.

EDIT:
Propsize = 72
SizeOf = 16
PropItem.Length = 56

Hmmmm :wall:


gruss

Uwe Raabe 19. Mär 2017 21:54

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364785)
Ich denke mal das er einfach global deklariert werden muss damit die Daten nicht überschrieben werden.

Wohl eher: damit andere Daten überschrieben werden.

Zitat:

Zitat von EWeiss (Beitrag 1364785)
Ich habe das geprüft und die Daten kommen alle richtig an.

EDIT:
Propsize = 72
SizeOf = 16
PropItem.Length = 56

Daraus schließe ich, daß jetzt die ersten 56 Byte hinter dem PropItem Feld überschrieben werden. Deklariere dort doch zum Test mal einen entsprechend großen Bereich, initialisiere ihn (sollte sowieso alles 0 sein) und schau nach, was nach dem Aufruf drin steht. Würde mich auch nicht wundern, wenn der Value-Pointer genau auf diesen Bereich zeigt.

EWeiss 19. Mär 2017 21:58

AW: Array of Integer und crash
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1364786)
Zitat:

Zitat von EWeiss (Beitrag 1364785)
Ich denke mal das er einfach global deklariert werden muss damit die Daten nicht überschrieben werden.

Wohl eher: damit andere Daten überschrieben werden.

Zitat:

Zitat von EWeiss (Beitrag 1364785)
Ich habe das geprüft und die Daten kommen alle richtig an.

EDIT:
Propsize = 72
SizeOf = 16
PropItem.Length = 56

Daraus schließe ich, daß jetzt die ersten 56 Byte hinter dem PropItem Feld überschrieben werden. Deklariere dort doch zum Test mal einen entsprechend großen Bereich, initialisiere ihn (sollte sowieso alles 0 sein) und schau nach, was nach dem Aufruf drin steht. Würde mich auch nicht wundern, wenn der Value-Pointer genau auf diesen Bereich zeigt.

Sorry ich weis jetzt nicht was du meinst wie soll ich dem Record einen Speicher zuweisen.
Oder was meinst du genau.

Danke für deine Hilfe hab da echt ein Verständnis Problem.
gruss

Uwe Raabe 19. Mär 2017 22:09

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1364787)
Sorry ich weis jetzt nicht was du meinst wie soll ich dem Record einen Speicher zuweisen.

Das kannst du so gar nicht. Deswegen wird in den Beispielen auch immer ein dynamischer Pointer PPropertyIem benutzt, der entsprechend PropSize alloziert wird.

Delphi-Quellcode:
   PropSize: UINT;
   PropItem: PPropertyItem; // dynamischer Pointer auf Record


  if GDIP_GetPropertyItemSize(InGifImage, PropertyTagFrameDelay, PropSize) = S_OK then
  begin
    GetMem(PropItem, PropSize); // Record in passender Größe bereitstellen
    // Daten auslesen
    if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem^) = S_OK then // Alternativ den Typ des Parameters in PPropertyItem ändern
    ...
    FreeMem(PropItem); // Delphi merkt sich die Size intern

EWeiss 19. Mär 2017 22:13

AW: Array of Integer und crash
 
Zitat:

Das kannst du so gar nicht. Deswegen wird in den Beispielen auch immer ein dynamischer Pointer PPropertyIem benutzt, der entsprechend PropSize alloziert wird.
Jo das meinte ich doch ;) Danke.

So wie du sagst es gibt immer noch Probleme eigentlich müsste ich als Ergebnis für jedes Frame 80 MS Wartezeit haben.
Die sind aber nicht richtig da die Daten durcheinander sind die Ankommen.

Danke werde mal das Memory so allokieren wie du gezeigt hast.

gruss

EWeiss 19. Mär 2017 22:30

AW: Array of Integer und crash
 
Es geht nicht wirklich musste es ändern da sich die Typen nicht vertragen haben.

TProp musste ich umdefinieren..
Delphi-Quellcode:
  TProp = array of Byte;
Delphi-Quellcode:
var
  p: Pointer;
//###############
// Bytearray dimensionieren
p := @PropItem;
GetMem(p, PropSize);

SetLength(Prop, (PropItem.length - 1));
CopyMemory(@Prop[0], @PropItem.value, PropItem.length);

FreeMem(p);
Hab irgendwo ein denk Fehler.
Die Einträge nach meinem Verständnis müssten eigentlich so aussehen
8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0

Sehen aber aus wie im Bild gezeigt.
Irgendwas stimmt noch nicht. (Ein durcheinander)
NA ja hab mich noch nicht wirklich mit dem GIF Kram auseinandergesetzt.


gruss

Uwe Raabe 19. Mär 2017 22:32

AW: Array of Integer und crash
 
Versuch doch mal so (value ist doch ein Pointer auf den Datenbereich):

Delphi-Quellcode:
CopyMemory(@Prop[0], PropItem.value, PropItem.length);

EWeiss 19. Mär 2017 22:35

AW: Array of Integer und crash
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1364792)
Versuch doch mal so (value ist doch ein Pointer auf den Datenbereich):

Delphi-Quellcode:
CopyMemory(@Prop[0], PropItem.value, PropItem.length);

Geht auch ohne Pointer aber die Daten sind immer noch durcheinander.

gruss

Uwe Raabe 19. Mär 2017 22:47

AW: Array of Integer und crash
 
Das sieht aber immer noch nicht so aus, wie ich das gezeigt hatte:

Delphi-Quellcode:
var
  p: Pointer;
//###############
// Bytearray dimensionieren
p := @PropItem;
GetMem(p, PropSize);

SetLength(Prop, (PropItem.length - 1));
CopyMemory(@Prop[0], @PropItem.value, PropItem.length);

FreeMem(p);

So sollte es auch mit dem Prop-Array gehen:

Delphi-Quellcode:
   PropSize: UINT;
   PropItem: PPropertyItem; // dynamischer Pointer auf Record, deswegen PPropertyItem und nicht TPropertyItem


  if GDIP_GetPropertyItemSize(InGifImage, PropertyTagFrameDelay, PropSize) = S_OK then
  begin
    GetMem(PropItem, PropSize); // Record in passender Größe bereitstellen
    // Daten auslesen
    if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem^) = S_OK then begin
      SetLength(Prop, PropItem.length); // nix -1 !!!
      CopyMemory(@Prop[0], PropItem.value, PropItem.length);    
      ...
    end;
    FreeMem(PropItem); // Delphi merkt sich die Size intern

EWeiss 19. Mär 2017 22:58

AW: Array of Integer und crash
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1364794)
Das sieht aber immer noch nicht so aus, wie ich das gezeigt hatte:


Sorry das mit GetMem funktioniert nicht.
GetMem erwartet einen Pointer PropItem ist aber als TPropertyItem definiert.
Was aber korrekt ist ich muss den Speicher vor GetPropertyItem allokieren ich habe es nachher gemacht.


EDIT:
OK hab dich verstanden funktioniert jetzt ;)
Danke für deine Mühe und Zeit.
Habe wieder einiges gelernt. :)

So soll es sein das Ergebniss.. jedes Frame läuft 80ms.
Hier nochmal das gesamt Ergebnis vielleicht kann es ja mal jemand brauchen.

Delphi-Quellcode:
procedure TAnimateGif.GetGifFrameDelays(GifImage: Cardinal; FrameCount: UINT;
  var FrameDelay: TFrameDelay);
var
  ISize: integer;
  PropSize: UINT;
  Prop: TProp;
  PropCount: integer;
begin

  ISize := 0;

  // Datengröße vom EXIF-Tag PropertyTagFrameDelay ermitteln
  if GDIP_GetPropertyItemSize(GifImage, PropertyTagFrameDelay, PropSize) = S_OK then
  begin
    // Speicher allokieren
    GetMem(PropItem, PropSize);
   
    // Daten auslesen
    if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
    begin
      // Bytearray dimensionieren
      SetLength(Prop, (PropItem.length + 1));
      CopyMemory(@Prop[0], PropItem.value, PropItem.length);

      // PropertyTyp ermitteln
      case PropItem.type_ of
        PropertyTagTypeByte:
          ISize := 1;

        PropertyTagTypeShort:
          ISize := 2;

        PropertyTagTypeLong:
          ISize := 4;
      end;

      // Array zur Aufnahme der Pausenzeiten dimensionieren
      SetLength(FrameDelay, FrameCount);
      // Pausenzeiten der einzelnen Bilder aus Bytearray kopieren
      for PropCount := 0 to (FrameCount - 1) do
      begin
        CopyMemory(@FrameDelay[PropCount], @Prop[PropCount * ISize], ISize);
        FrameDelay[PropCount] := FrameDelay[PropCount] * 10;
      end;
    end;
    FreeMem(PropItem);
  end;

end;
gruss

EWeiss 26. Sep 2018 13:28

AW: Array of Integer und crash
 
Muss das nochmal aufgreifen..

Habe das Projekt nach 64 Bit umgelegt bekomme aber jetzt fortlaufend "Inaccessible value"
Delphi-Quellcode:
function TAnimateGif.GetPropertyItem(GifImage: LONG_PTR; PropertyID: ULONG; PropertyItemSize: UINT;
  var PropertyItemData: PPropertyItem): GPSTATUS;
begin

  // Daten auslesen
  Result := GDIP_GetPropertyItem(GifImage, PropertyID, PropertyItemSize, PropertyItemData);
end;
Delphi-Quellcode:
function GDIP_GetPropertyItem(Img: LONG_PTR; propId: PROPID; propSize: UINT;
  var buffer: PPROPERTYITEM
): GPSTATUS; stdcall;
begin

  result := GdipGetPropertyItem(Img, propId, propSize, buffer);
end;
bevor GdipGetPropertyItem aufgerufen wird ist der Buffer gefüllt.
Nach dem Aufruf von GdipGetPropertyItem ist der buffer Inaccessible.

Wie immer tritt nur unter 64 Bit auf.

Die Funktion ist diese.
Delphi-Quellcode:
GdipGetPropertyItem: function(Image: LONG_PTR; propId: PROPID; propSize: UINT; var buffer: PPROPERTYITEM): GPSTATUS; stdcall;


Und der Record der..
Delphi-Quellcode:
  PropertyItem = record // NOT PACKED !!
    id      : PROPID; // ID of this property
    length  : ULONG;  // Length of the property value, in bytes
    type_    : WORD;   // Type of the value, as one of TAG_TYPE_XXX
    value   : Pointer; // property value
  end;
  TPropertyItem = PropertyItem;
  PPropertyItem = ^TPropertyItem;
es kracht dann hier
Delphi-Quellcode:
    // Daten auslesen
    if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, FPropItem) = OK then
    begin
      // Bytearray dimensionieren
      SetLength(Prop, PropItem.Length);
      CopyMemory(@Prop[0], PropItem.value, PropItem.Length);
weil PropItem bzw. vorher schon PropertyItemData nicht zugänglich ist.

PS:
Es hat nichts mit dem setzen der Optimierung zu tun!

gruss

TiGü 26. Sep 2018 14:11

AW: Array of Integer und crash
 
Zitat:

Zitat von EWeiss (Beitrag 1414255)
Delphi-Quellcode:
    // Daten auslesen
    if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, FPropItem) = OK then
    begin
      // Bytearray dimensionieren
      SetLength(Prop, PropItem.Length);
      CopyMemory(@Prop[0], PropItem.value, PropItem.Length);

Du füllst FPropItem und greifst dann auf PropItem (ohne F) zu.

EWeiss 26. Sep 2018 14:15

AW: Array of Integer und crash
 
Zitat:

Zitat von TiGü (Beitrag 1414260)
Zitat:

Zitat von EWeiss (Beitrag 1414255)
Delphi-Quellcode:
    // Daten auslesen
    if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, FPropItem) = OK then
    begin
      // Bytearray dimensionieren
      SetLength(Prop, PropItem.Length);
      CopyMemory(@Prop[0], PropItem.value, PropItem.Length);

Du füllst FPropItem und greifst dann auf PropItem (ohne F) zu.

FPropItem ist nicht zugänglich. (Inaccessible)
Und ja das gleiche tue ich auch unter 32 Bit ohne Probleme..

Danke.
Der Fehler den ich bekomme ist EInOutError..

zudem es ist ein Property
Delphi-Quellcode:
property PropItem: PPropertyItem read FPropItem write FPropItem;


FPropItem liest und weist das Result PropItem zu beide haben also den gleichen Wert.

gruss

TiGü 26. Sep 2018 14:20

AW: Array of Integer und crash
 
Reservierst du denn vorher Speicher von der Größe, die dir GdipGetPropertyItemSize liefert, für deine Membervariable FPropItem bzw. für das dahinterliegende Record?

EWeiss 26. Sep 2018 14:23

AW: Array of Integer und crash
 
Zitat:

Zitat von TiGü (Beitrag 1414262)
Reservierst du denn vorher Speicher von der Größe, die dir GdipGetPropertyItemSize liefert, für deine Membervariable FPropItem bzw. für das dahinterliegende Record?

Ja..
Delphi-Quellcode:
  // Datengröße vom EXIF-Tag PropertyTagFrameDelay ermitteln
  if GDIP_GetPropertyItemSize(GifImage, PropertyTagFrameDelay, PropSize) = OK then
  begin
    // Speicher allokieren
    GetMem(FPropItem, PropSize);
gruss

TiGü 26. Sep 2018 14:39

AW: Array of Integer und crash
 
Ein kleines 20-50 Zeilenprogramm zum nachvollziehen und selber kompilieren?


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr.
Seite 1 von 2  1 2      

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