Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Dynamisches Array Grenze? (https://www.delphipraxis.net/167418-dynamisches-array-grenze.html)

EWeiss 28. Mär 2012 18:43

Dynamisches Array Grenze?
 
Beim einlesen vom Desktop hat mein Array eine grenze von 1920x1200 = 2304000

Gibt es eine Obergrenze in Delphi für dynamische Arrays also 65535 ?
Denke nicht oder?

Auf jedenfall tritt jetzt ein Fehler auf
Zitat:

Erste Gelegenheit für Exception bei $76D5B9BC. Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung bei Adresse 003618F6 in Modul 'Dimmed.dll'. Lesen von Adresse 041DA000'. Prozess DimmedTest.exe (4044)
Leider mal wieder nicht zu identifizieren was da abgeht.
Kann ja nicht über 2 Millionen Pixel debuggen.

EDIT:
131071 macht er zu größer scheint das Array nicht zu dimensionieren zu sein.
CreateDIBSection will nicht mehr rausspucken. Das ist mein Problem denke ich nicht das Array.

Was für ein Sch...s


gruss

FlatIron 28. Mär 2012 18:55

AW: Dynamisches Array Grenze?
 
http://stackoverflow.com/questions/9...rray-in-delphi

Solltest eigentlich genug Platz haben. Oder habe ich da was falsch verstanden? Mehr kann ich leider nicht dazu sagen

EDIT: Ich hätte besser noch weiter gelesen. Hier steht noch was zur Praxis:
http://stackoverflow.com/a/985108

Das hätte das Problem erklären können, hätte es am Array gelegen ;)

himitsu 28. Mär 2012 19:28

AW: Dynamisches Array Grenze?
 
Delphi-Quellcode:
MaxLength := (High(Integer) - 2 * SizeOf(Integer)) div SizeOf(MyArray[0]);

// für 32-Bit-Delphi
type
  TMyArray = array of XXX;

MaxLength := ($7FFFFFFF - 8) div SizeOf(XXX);
MaxLength := Trunc(2147483639 / SizeOf(XXX));
Das währe die technische Seite. (Referenzzählung+Länge+Daten)
> stackoverflow erzählt halt manchmal auch nur Mist.

Real ist nur soviel möglich, wie der größte zusammenhängende freie Speicherblock an Platz bietet.

EWeiss 28. Mär 2012 19:28

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von FlatIron (Beitrag 1159133)
http://stackoverflow.com/questions/9...rray-in-delphi

Solltest eigentlich genug Platz haben. Oder habe ich da was falsch verstanden? Mehr kann ich leider nicht dazu sagen

JO liegt nicht am Array das problem ist CreateDIBSection gibt mir nicht mehr wie 131071 Pixel.
Wieder mal ein Delphi problem in C++ gibts das nicht.

grrr..

Pixels sind nicht vollständig.

gruss

brechi 28. Mär 2012 20:48

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von EWeiss (Beitrag 1159137)
Zitat:

Zitat von FlatIron (Beitrag 1159133)
http://stackoverflow.com/questions/9...rray-in-delphi

Solltest eigentlich genug Platz haben. Oder habe ich da was falsch verstanden? Mehr kann ich leider nicht dazu sagen

JO liegt nicht am Array das problem ist CreateDIBSection gibt mir nicht mehr wie 131071 Pixel.
Wieder mal ein Delphi problem in C++ gibts das nicht.

grrr..

gruss

Das ist mit Sicherheit kein Delphi Problem weils ne WinAPI ist die genauso unter Delphi wie auch unter C++ funktioniert. Das Problem wird da eher vorm Bildschirm sitzen :wink:

EWeiss 28. Mär 2012 21:09

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von brechi (Beitrag 1159143)
Das Problem wird da eher vorm Bildschirm sitzen :wink:

Ach ja?
Dann sag mir doch mal bitte welchen Einfluss ich auf CreateDIBSection nehmen kann
wenn ich nur 131071 Pixel zurück geiefert bekomme?

Bekomme ich mehr gebe ich dir recht .. andernfalls na ja du weist schon ;)

Code? OK!

Delphi-Quellcode:
begin

  hRetBmp := 0;

   if hBmp <> 0 then
   begin
      hBufferDC := CreateCompatibleDC(0);
      if hBufferDC <> 0 then
      begin
      hTmpBitmap := 0;
         if hBmpDC <> 0 then
            if (hBmp = GetCurrentObject(hBmpDC, OBJ_BITMAP)) then
            begin
               hTmpBitmap := CreateBitmap(1, 1, 1, 1, nil);
               SelectObject(hBmpDC, hTmpBitmap);
            end;

         hPrevBufObject := SelectObject(hBufferDC, hBmp);

         hDirectDC := CreateCompatibleDC(0);
         if hDirectDC <> 0 then
         begin
            GetObject(hBmp, sizeof(bm), @bm);

           ZeroMemory(@bmInfo, sizeof(BITMAPINFO));
            bmInfo.bmiHeader.biSize        := sizeof(bmInfo.bmiHeader);
            bmInfo.bmiHeader.biWidth     := bm.bmWidth;
            bmInfo.bmiHeader.biHeight     := bm.bmHeight;
            bmInfo.bmiHeader.biPlanes     := 1;
            bmInfo.bmiHeader.biBitCount   := 32;

            hDirectBitmap := CreateDIBSection(hDirectDC, bmInfo, DIB_RGB_COLORS, Pointer(Pixels), 0, 0);
            if hDirectBitmap <> 0 then

gruss

brechi 28. Mär 2012 21:37

AW: Dynamisches Array Grenze?
 
Delphi-Quellcode:
var
  tempBitmap: BITMAPINFO;
  pvBits: Pointer;
  mDC: THandle;
  mainBitmap: Thandle;
  x, y: integer;
  q: ^TRGBTriple;
  idx: integer;
begin
  ZeroMemory(@tempBitmap, sizeof(BITMAPINFO));
  tempBitmap.bmiHeader.biSize := SizeOf(BITMAPINFOHEADER);
  tempBitmap.bmiHeader.biBitCount := 24;
  tempBitmap.bmiHeader.biWidth := 1920;
  tempBitmap.bmiHeader.biHeight := 1080;
  tempBitmap.bmiHeader.biPlanes := 1;
  tempBitmap.bmiHeader.biCompression := BI_RGB;
  tempBitmap.bmiHeader.biSizeImage := tempBitmap.bmiHeader.biWidth * tempBitmap.bmiHeader.biHeight * 3;
  mDC := CreateCompatibleDC(0);
  mainBitmap := CreateDIBSection(mDC, tempBitmap, DIB_RGB_COLORS, pvBits, 0, 0);
  SelectObject(mDC, mainBitmap);
  FillChar(pvBits^, tempBitmap.bmiHeader.biWidth * tempBitmap.bmiHeader.biHeight * 3, 255);
  for y := 0 to tempBitmap.bmiHeader.biHeight - 1 do begin
    for x := 0 to tempBitmap.bmiHeader.biWidth - 1 do begin
      idx := y * tempBitmap.bmiHeader.biWidth + x;
      q := Pointer(Integer(pvBits) + idx * 3);
      q.rgbtBlue := Round(x * 255 / tempBitmap.bmiHeader.biWidth);
      q.rgbtRed := Round(y * 255 / tempBitmap.bmiHeader.biHeight);
      q.rgbtGreen := 55;
    end;
  end;
  BitBlt(canvas.Handle, 0, 0, tempBitmap.bmiHeader.biWidth, tempBitmap.bmiHeader.biHeight, mDC, 0, 0, SRCCOPY);
hab mir den aufräum Code jetzt mal gespart

-> du setzt bei dir die Bildgroesse nicht: bmInfo.bmiHeader.biBitCount := tempBitmap.bmiHeader.biWidth * tempBitmap.bmiHeader.biHeight * tempBitmap.bmiHeader.biBitCount div 8

EWeiss 28. Mär 2012 21:48

AW: Dynamisches Array Grenze?
 
Nu was ist bei dir anders als bei mir?
Im Pointer(Pixels) ist das array welches von CreateDIBSection zurück geliefert wird.
Das ist ja das schöne daran das ich mir so das suchen der pixels mit GetPixel sparen kann.
Was soll ich nun machen das mir die richtige Anzahl abhängig vom Bild (Bilddimension) zurückgegeben wird?


gruss

isilive 28. Mär 2012 21:58

AW: Dynamisches Array Grenze?
 
Hab gestern dynamische Arrays gebraucht. Da war Schluss bei 33 Mio. Elementen und einem theoretischen Ramverbrauch von Arraycount x Elementsize(40 Bytes) = 1,3GB. Grösser ging dann nicht mehr. Win7 32bit, kein 3GB Switch aktiviert.

EWeiss 28. Mär 2012 22:01

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von isilive (Beitrag 1159150)
Hab gestern dynamische Arrays gebraucht. Da war Schluss bei 33 Mio. Elementen und einem theoretischen Ramverbrauch von Arraycount x Elementsize(40 Bytes) = 1,3GB. Grösser ging dann nicht mehr. Win7 32bit, kein 3GB Switch aktiviert.

Das ist auch nicht mein problem.. Danke schön :)
Habe ja schon festgestellt woran es liegt CreateDIBSection gibt mir nicht die korrekte anzahl an pixel

gruss

Sir Rufo 29. Mär 2012 01:27

AW: Dynamisches Array Grenze?
 
Im MSDN reiten die für hSection so auf NULL herum, dann würde die API auch den Speicher reservieren. Wenn nicht NULL, dann muss man den Speicher selber bereitstellen.

Also evtl. so?
Delphi-Quellcode:
hDirectBitmap := CreateDIBSection(hDirectDC, bmInfo, DIB_RGB_COLORS, Pointer(Pixels), NULL, 0);

EWeiss 29. Mär 2012 02:10

AW: Dynamisches Array Grenze?
 
Das werd ich mal testen Danke.
Nur wo ist NULL deklariert .. hmm OK in Variants

Leider nicht
Zitat:

Erste Gelegenheit für Exception bei $7715B9BC. Exception-Klasse EVariantTypeCastError mit Meldung 'Variante des Typs (Null) konnte nicht in Typ (Int64) konvertiert werden'. Prozess DimmedTest.exe (344)
Zitat:

dann muss man den Speicher selber bereitstellen.
Wenn ich jetzt wüßte wie, bezogen auf diese function, dann wäre es ja gut ;)

EDIT:
Sieht so aus
Zitat:

If hSection is not NULL, it must be a handle to a file mapping object created by calling the CreateFileMapping function.
Mein Problem das ich aber habe verfüge nur über ein HBitmap und lade keine Datei.
Könnte den hFile parameter mit INVALID_HANDLE_VALUE befüllen aber ob es damit getan ist?
Warum stellt Delphi den Parameter NULL zur verfügung wenn es nicht damit umgehen kann.
Oder ich bin einfach zu :stupid::wall:

In C++ sieht es so aus
Code:
HBITMAP hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmi, DIB_RGB_COLORS,(void**)&ppvBits , NULL, 0);
Anders hab ich es auch nicht, abgesehen von "NULL"
Hab mit CreateDIBSection schon viel gemacht aber das schlägt dem Fass den Boden aus. :pale:

gruss

himitsu 29. Mär 2012 08:11

AW: Dynamisches Array Grenze?
 
Zitat:

Nur wo ist NULL deklariert .. hmm OK in Variants
Fast, das NULL ist Variants ist ein Variant mit dem Wert NULL,
aber das hat mit diesem NULL nichts gemeinsam.

nil oder 0, je nach dem, ob der Parameter als Zeigertyp oder als ordinaler Typ deklariert ist.

Blup 29. Mär 2012 08:14

AW: Dynamisches Array Grenze?
 
Das ist in erster Linie ein Problem des Grafiktreibers.
Je nach Grafikkarte und Hersteller kann auch schon bei 1024x768 Schluss sein.
Allgemein kann man sich nicht darauf verlassen das man größere geräteabhängige Bitmaps erzeugen kann, als die maximal darstellbar Auflösung der Hardware hergibt.

EWeiss 29. Mär 2012 13:22

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von Blup (Beitrag 1159177)
Das ist in erster Linie ein Problem des Grafiktreibers.
Je nach Grafikkarte und Hersteller kann auch schon bei 1024x768 Schluss sein.

Wäre es ein Grafikkarten problem dann würde diese Abfrage fehlschlagen.
Delphi-Quellcode:
  ClientDC := GetWindowDC(ParentHandle);
  if (GetDeviceCaps(ClientDC, RASTERCAPS) and RC_PALETTE = RC_PALETTE) then
  begin
    Result := False;
    exit;
  end;
Zumal bei einer Grafikkarte Gforce gtx 460 1GB (GPU Ram)eingestellter Auflösung von 1920x1200
8GB ram / Speicher kein Problem sein dürfte.

Zitat:

Allgemein kann man sich nicht darauf verlassen das man größere geräteabhängige Bitmaps erzeugen kann, als die maximal darstellbar Auflösung der Hardware hergibt.
Tue ich auch nicht wenn überhaupt dann die aktuelle größe des Desktop.

Außerdem habe ein programm in C++ getestet ohne Bildmanipulation und dort wird der Speicher
bzw.. die richtige anzahl von Pixeln auf meinem System ohne Probleme verwaltet.

Zitat:

nil oder 0, je nach dem, ob der Parameter als Zeigertyp oder als ordinaler Typ deklariert ist.
Jo und das habe ich ja also 0 für Cardinal.

gruss

TiGü 29. Mär 2012 15:01

AW: Dynamisches Array Grenze?
 
Hau doch mal den ganzen Quelltext von der DLL raus, sonst kann doch keiner richtig debuggen.
Sonst stocheren wir hier nur so rum und das Problem ist vielleicht ganz woanderes.

EWeiss 29. Mär 2012 15:24

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von TiGü (Beitrag 1159265)
Hau doch mal den ganzen Quelltext von der DLL raus, sonst kann doch keiner richtig debuggen.
Sonst stocheren wir hier nur so rum und das Problem ist vielleicht ganz woanderes.

Deinen Wunsch wurde entsprochen ;)

gruss

Blup 29. Mär 2012 16:14

AW: Dynamisches Array Grenze?
 
Das Problem scheint zumindest ähnlich zu sein:
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Zitat:

Systemwide size limitations
Windows apparently may enforce systemwide limits on available memory for CreateCompatibleBitmap. (According to some sources, this is because device-dependent bitmaps must reside in video card RAM.) If you're getting ERROR_NOT_ENOUGH_MEMORY errors when calling CreateCompatibleBitmap, the solution is to use device-independent bitmaps (DIBs) instead.

brechi 29. Mär 2012 16:21

AW: Dynamisches Array Grenze?
 
Ähm du solltest keine Dyn. Arrays als Output einer Funktion verwenden, da u.a. z.b. noch die Laenge gespeichert wird. (Genau müsste ich da jetzt auch erstmal nachschauen)
Du kannst eher sowas nehmen:
Delphi-Quellcode:
type
   TMyPixels = array[0..4096*4096-1] of Cardinal;
   PMyPixels = ^TMyPixels;
var
  Pixels: PPixels;
CreateDIBSection(....,Pixels,....);
Pixels[0]...
Außerdem solltest du in deinem Code mal die globalen Variablen entfernen. Und zu guter letzt: Lies dir nochmal meinen 2. Post mit meinem Beispiel KOMPLETT durch, da solltest die Lösung finden.

Ubrigens hast du da noch mehr Fehler im Code. Bei:
Delphi-Quellcode:
          nSize := bm.bmWidth * bm.bmHeight;

          for IntI := 0 to nSize do
fehlt mit Sicherheit ein -1
und statt einem "array of cardinal" bietet sich wohl auch ein "array of TRGBQuad" oder eine eigene Definition an.

EWeiss 29. Mär 2012 18:08

AW: Dynamisches Array Grenze?
 
Zitat:

Und zu guter letzt: Lies dir nochmal meinen 2. Post mit meinem Beispiel KOMPLETT durch, da solltest die Lösung finden.
Habe deinen Thread schon gelesen aber lösungen sind da keine was den Speicher angeht.
Zitat:

Delphi-Quellcode:
type
    TMyPixels = array[0..4096*4096-1] of Cardinal;
    PMyPixels = ^TMyPixels;
 var
   Pixels: PPixels;
 CreateDIBSection(....,Pixels,....);
 Pixels[0]...

Eine alternative aber kein muss ;) Verstehe hier den zusammenhang nicht in verbindung mit dem Speicher.
CreateDibSection gibt die Pixelanzahl selbst zurück also dimensioniert den Speicher im normalfall selbst.
Wenn aber hSection nicht gleich NULL ist benötige ich ein mapping.
Das geht aber über HBitmap nicht.

Zitat:

Delphi-Quellcode:
nSize := bm.bmWidth * bm.bmHeight;
for IntI := 0 to nSize do
fehlt mit Sicherheit ein -1
Ok wo du Recht hast .. hast du recht.

bmInfo.bmiHeader.biBitCount kannst du nicht einfach so festlegen (bzw. selbst berechen) dafür gibt es vorgaben abhängig vom Bitmap
also 1,4,8,16,24 bis Win98 und 1,4,8,16,24,32 Bit ab Win2000

Siehe BitCount

Quelltext ist ja oben..
Wenn zeit hast kannst es ja berichtigen.

Kannst das bitte im Thread Dimmed Sample posten ?
Da es ja jetzt nicht mehr um das Array alleine geht.
Danke.

EDIT:
Es lag wirklich nur an nSize -1

gruss

brechi 29. Mär 2012 22:45

AW: Dynamisches Array Grenze?
 
Wie gesagt, ein dynamisches array solltest du nicht verwenden. Un mit dem ganzen post lesen war folgendes gemeint:
Delphi-Quellcode:
bmInfo.bmiHeader.biSizeImage := tempBitmap.bmiHeader.biWidth * tempBitmap.bmiHeader.biHeight * tempBitmap.bmiHeader.biBitCount div 8;
ich hatte mich mit SizeImage und BitCount vertan (ist in meinem Bsp. aber richtig) -> du setzt biSizeImage nicht

himitsu 29. Mär 2012 23:15

AW: Dynamisches Array Grenze?
 
Nur daß oftmals die Datengrößen der einzelnen Zeilen auf ganze Integer (4 Byte) aufgerundet werden, was man bei der Berechnung eventuell noch beachten müßte.

EWeiss 29. Mär 2012 23:23

AW: Dynamisches Array Grenze?
 
Zitat:

Zitat von brechi (Beitrag 1159318)
Wie gesagt, ein dynamisches array solltest du nicht verwenden. Un mit dem ganzen post lesen war folgendes gemeint:
Delphi-Quellcode:
bmInfo.bmiHeader.biSizeImage := tempBitmap.bmiHeader.biWidth * tempBitmap.bmiHeader.biHeight * tempBitmap.bmiHeader.biBitCount div 8;
ich hatte mich mit SizeImage und BitCount vertan (ist in meinem Bsp. aber richtig) -> du setzt biSizeImage nicht

Also mein problem zur zeit das ich noch habe ist das nach einem Klick der Speicherverbrauch jetzt Rapide nach oben geht.
Bei der Form sind es 45MB und jetzt kommt's beim Desktop 900plus

Irgendwo hapert es da noch ganz schön.
Hab viel vergessen nach meiner Krankheit das ist Fakt :)

Was ist besser an einem 1 Dimensionalen statischen Array?
Also was bringt es an Geschwindigkeit ich habe es ja versucht kann aber den vorteil nicht erkennen
Funktionieren tut es natürlich auch.

mit biSizeImage werde ich auch nochmal versuchen .. Danke

EDIT:
Jup das hat mir geholfen der Tip mit dem Statischen Array
wird jetzt kein Speicher mehr verschwendet 2 MB sind OK da kann man mit leben.

biSizeImage hab ich mal addiert obwohl mir im moment nicht ganz klar ist
was mir das bringt in verbindung mit CreateDibSection.
Es wird nirgendwo verwendet.

Danke für eure Hilfe.

gruss


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