AGB  ·  Datenschutz  ·  Impressum  







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

Array of Integer und crash

Ein Thema von EWeiss · begonnen am 19. Mär 2017 · letzter Beitrag vom 27. Sep 2018
Antwort Antwort
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.652 Beiträge
 
Delphi 12 Athens
 
#1

AW: Array of Integer und crash

  Alt 19. Mär 2017, 17:51
Warum werden die Wert verändert.
Das lässt sich anhand dieser kurzen Code-Fragmente nicht erkennen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: Array of Integer und crash

  Alt 19. Mär 2017, 18:47
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
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
SetLength(OutFrameDelay, (InFrameCount - 1));

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.652 Beiträge
 
Delphi 12 Athens
 
#3

AW: Array of Integer und crash

  Alt 19. Mär 2017, 21:00
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Array of Integer und crash

  Alt 19. Mär 2017, 21:06
Die frage die da wäre welchen Buffer?

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: Array of Integer und crash

  Alt 19. Mär 2017, 21:08
PropItem
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Array of Integer und crash

  Alt 19. Mär 2017, 21:16
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
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Array of Integer und crash

  Alt 19. Mär 2017, 21:27
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.

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
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.652 Beiträge
 
Delphi 12 Athens
 
#8

AW: Array of Integer und crash

  Alt 19. Mär 2017, 21:31
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort


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:11 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