![]() |
Array of Integer und crash
Ich hab ein Array of Integer in einer Procedure definiert.
Delphi-Quellcode:
wenn ich nun das Array redimensioniere dann kracht es mal wieder.
type
TOutFrameDelay = array of Integer; POutFrameDelay = ^TOutFrameDelay; .... procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: UINT; var OutFrameDelay: TOutFrameDelay);
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 |
AW: Array of Integer und crash
Moin...8-)
Was spricht gegen TList<Integer>. Da hast du das Pointer geschubse nicht. :wink: |
AW: Array of Integer und crash
Zitat:
Eigentlich müsste das doch funktionieren frage mich nur warum nicht. gruss |
AW: Array of Integer und crash
Zitat:
|
AW: Array of Integer und crash
Delphi-Quellcode:
Habe gelesen das man hier den var Parameter übergeben soll wenn eine Type Deklaration für das Array angelegt wurde.
var OutFrameDelay: TOutFrameDelay
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 |
AW: Array of Integer und crash
Zitat:
|
AW: Array of Integer und crash
Zitat:
Delphi-Quellcode:
procedure GetGifFrameDelays(InGifImage: Cardinal; InFrameCount: UINT;
var OutFrameDelay: TOutFrameDelay);
Delphi-Quellcode:
Jetzt brat mir einer nen Storch warum geht das nicht.
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; grrrr... LOL gruss |
AW: Array of Integer und crash
Zitat:
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. |
AW: Array of Integer und crash
Zitat:
der Pointer muß auf Myarray[0] zeigen. (ich hab jedenfalls keine Zuweisung gesehen?) Gruß K-H |
AW: Array of Integer und crash
Dank euch muss mir das nochmal ansehen.
Bin jetzt wieder dabei. ;)
Delphi-Quellcode:
Wie ? Wenn ich das Array vorher nicht dimensionieren kann.
der Pointer muß auf Myarray[0] zeigen.
Es ist ja dann noch nicht mal initialisiert ohne SetLength. gruss |
AW: Array of Integer und crash
Delphi-Quellcode:
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.
type
TOutFrameDelay = array of Integer; POutFrameDelay = ^TOutFrameDelay; |
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 |
AW: Array of Integer und crash
Zitat:
Hmm.. :wall: gruss |
AW: Array of Integer und crash
Zitat:
Delphi-Quellcode:
, sondern an irgendeiner anderen Stelle mit Bezug auf
SetLength
Delphi-Quellcode:
.
InGifImage
|
AW: Array of Integer und crash
Zitat:
Wo soll dann was falsch sein wenn der Compiler mir true zurück gibt. Ich denke das muss ich selber suchen/Fixen. Danke gruss |
AW: Array of Integer und crash
Nach dem Aufruf
Delphi-Quellcode:
if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
begin
Delphi-Quellcode:
nach begin..
function GetPropertyItem(InGifImage: Cardinal; PropertyID: ULONG; PropertyItemSize: UINT;
var PropertyItemData: TPropertyItem): integer; begin // Daten auslesen Result := GDIP_GetPropertyItem(InGifImage, PropertyID, PropertyItemSize, @PropertyItemData); end; 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 |
AW: Array of Integer und crash
Zitat:
|
AW: Array of Integer und crash
Zitat:
Delphi-Quellcode:
So das war's.
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; nachdem die Rückgabe erfolgt ist, in
Delphi-Quellcode:
nach begin
TAnimateGif.GetGifFrameDelays
Delphi-Quellcode:
Verändert sich der wert von InGifImage und PropSize beide haben dann den Wert 8.
if GetPropertyItem(InGifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
begin Hier kracht es dann
Delphi-Quellcode:
SetLength(OutFrameDelay, (InFrameCount - 1));
gruss |
AW: Array of Integer und crash
In der Doku zu GdipGetPropertyItem steht:
Zitat:
Delphi-Quellcode:
In der Folge ist der bereitgestellte Speicher für PropItem höchstwahrscheinlich nicht ausreichend und es werden wohl unkontrolliert andere Variablen überschrieben.
// 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 |
AW: Array of Integer und crash
Die frage die da wäre welchen Buffer?
gruss |
AW: Array of Integer und crash
Delphi-Quellcode:
PropItem
|
AW: Array of Integer und crash
Zitat:
Delphi-Quellcode:
Was für einen buffer soll ich da allokieren ?
PropertyItem = record
id : PROPID; length : ULONG; type_ : TPropertyTagType; value : Pointer; end; TPropertyItem = PropertyItem; PPropertyItem = ^TPropertyItem; PropItem: TPropertyItem; Die größe bzw. der Inhalt wird doch von der GdipGetPropertyItem zurück gegeben. gruss |
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:
kann man sehen das ich das PropItem hier deklariert habe.
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;
Delphi-Quellcode:
PropItem: TPropertyItem;
Diese habe ich nun herausgenommen und in meine Classe gesteckt.
Delphi-Quellcode:
Jetzt sag mir mal jemand warum das so ein Problem verursacht hat das es nach
TAnimateGif = class(TComponent)
private FSelectedIndex: Integer; PropItem: TPropertyItem;
Delphi-Quellcode:
jedes Mal gekracht hat und alle Variablen sich verändert haben.
if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, PropItem) = S_OK then
begin gruss |
AW: Array of Integer und crash
Zitat:
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:
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.
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 |
AW: Array of Integer und crash
Zitat:
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 |
AW: Array of Integer und crash
Zitat:
Zitat:
|
AW: Array of Integer und crash
Zitat:
Oder was meinst du genau. Danke für deine Hilfe hab da echt ein Verständnis Problem. gruss |
AW: Array of Integer und crash
Zitat:
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 |
AW: Array of Integer und crash
Zitat:
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 |
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:
Hab irgendwo ein denk Fehler.
var
p: Pointer; //############### // Bytearray dimensionieren p := @PropItem; GetMem(p, PropSize); SetLength(Prop, (PropItem.length - 1)); CopyMemory(@Prop[0], @PropItem.value, PropItem.length); FreeMem(p); 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 |
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);
|
AW: Array of Integer und crash
Zitat:
gruss |
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 |
AW: Array of Integer und crash
Zitat:
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:
gruss
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; |
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:
bevor GdipGetPropertyItem aufgerufen wird ist der Buffer gefüllt.
function GDIP_GetPropertyItem(Img: LONG_PTR; propId: PROPID; propSize: UINT;
var buffer: PPROPERTYITEM ): GPSTATUS; stdcall; begin result := GdipGetPropertyItem(Img, propId, propSize, buffer); end; 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:
es kracht dann hier
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;
Delphi-Quellcode:
weil PropItem bzw. vorher schon PropertyItemData nicht zugänglich ist.
// Daten auslesen
if GetPropertyItem(GifImage, PropertyTagFrameDelay, PropSize, FPropItem) = OK then begin // Bytearray dimensionieren SetLength(Prop, PropItem.Length); CopyMemory(@Prop[0], PropItem.value, PropItem.Length); PS: Es hat nichts mit dem setzen der Optimierung zu tun! gruss |
AW: Array of Integer und crash
Zitat:
|
AW: Array of Integer und crash
Zitat:
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 |
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?
|
AW: Array of Integer und crash
Zitat:
Delphi-Quellcode:
gruss
// Datengröße vom EXIF-Tag PropertyTagFrameDelay ermitteln
if GDIP_GetPropertyItemSize(GifImage, PropertyTagFrameDelay, PropSize) = OK then begin // Speicher allokieren GetMem(FPropItem, PropSize); |
AW: Array of Integer und crash
Ein kleines 20-50 Zeilenprogramm zum nachvollziehen und selber kompilieren?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:24 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