PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ChrigiGee
Beiträge: 125
Registriert: 18.07.2024 12:14
Computerausstattung: Lenovo ThinkPad i7, 32GB Ram, 1TB SSD
PB 6.11 LTS, proGUI, IceDesigner
Wohnort: Bern

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von ChrigiGee »

Hallo H. Brill,

Vereinfacht, ich muss einen Aufsatz schreiben.

Zwei Variablen stehen zur Verfügung.

Variable A = Minimum 5000 Worte umfasst der Text.
Variable B = das Maximum darf nicht über 100 Seiten kommen.

Die Variable C wäre die meine, mache ich jetzt den Aufsatz in Englisch oder in Deutsch.

Und dann beginne ich bei beiden Varianten etwas zu mischen, es kommt etwas Englisch mit rein
und dann auch mal wieder etwas Deutsch und am Schluss merke ich, dass ich völlig neben dem Ziel bin.

Ich komme mir immer noch vor wie ein kleines Kind, das noch immer sehr viel fragt,
um Zusammenhänge besser zu verstehen.

Herzliche Grüße
Christian
H.Brill hat geschrieben: 26.12.2024 09:19
ChrigiGee hat geschrieben: 26.12.2024 07:57 Das mit dem Speicherpuffer habe ich so annähernd begriffen.
Die Logik hatte ich noch nicht gesehen, dass er nicht direkt Relevanz hat,
für das Erstellen des pak Files resp. das entpacken. Musste ich wohl wirklich viel Zeit
aufwenden, bis ich es erkannte. Puffer als Konstante....
Betrachte mal so einen Speicherpuffer wie eine Universal - Variable, wo man praktisch alles
(Zahlen, Strings, sonst.Bytes) reinschreiben kann. Es ist halt ein Stück lineares RAM. Anders,
als bei Stringvariablen, die durch Anhängen (+) erweitert werden kann, muß so eine Speichervariable
ReAllociert werden, da man sonst über die Speichergrenze hinweg schreiben würde, was wieder
unvorhergesehene Reaktionen seitens des Betriebssystems hervorrufen kann.

Was die Herangehensweise betrifft, machst du das ja richtig. Ich selber schaue oft in die Hilfe,
probiere die kleinen Beispiele darin aus und integriere es anschließend in meinen eigenen
Quellcode. Nur Mut, kaputtmachen kannst du da nichts. Höchstens mal eine Datendatei, von
der man aber eine Kopie machen und damit arbeiten sollte.
Wer nicht fragt, der nichts lernt.
Wer keine Fehler macht, kann sich nicht verbessern.
Das Mysterium, ein wandelndes Lexikon. :mrgreen:

Wer Fragen zu meinem Textstil hat oder sich wundert über mich,
der darf seelenruhig mich direkt ansprechen. Ich beiße noch nicht.
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von H.Brill »

Wenn du damit meine Bezeichnung Universalvariable meinst.
Ich meine ja nur, bei Stringvariablen (.s) kommt Text rein und in numerische Variablen (.i, .l, .q)
kommen numerische Werte rein. In so einen Speicherbereich geht alles rein. Deshalb gibt es die verschiedenen
Poke- und Peek Varianten. Auch andere Zeichen, die kein Buchstabe oder Zahl sind, funktionieren.
Bei einer Memoryvariablen kannst du auch mischen, solange du die Wertigkeit vonz.b. numerischen
Variablen(4 Bytes) beachtest. Spiel (Pb_Ascii mal weglassen) doch einfach etwas damit :

Code: Alles auswählen

zahl.l = 1250
zeile.s = "Betrag : "
length.l = Len(zeile) + 1
*buffer = AllocateMemory(50)
PokeS(*buffer, zeile, length, #PB_Ascii)
PokeL(*buffer + length, zahl)
Debug MemorySize(*buffer)
Debug PeekS(*buffer, length, #PB_Ascii)
Debug PeekL(*buffer + length)
FreeMemory(*buffer)
PB 6.10
Benutzeravatar
ChrigiGee
Beiträge: 125
Registriert: 18.07.2024 12:14
Computerausstattung: Lenovo ThinkPad i7, 32GB Ram, 1TB SSD
PB 6.11 LTS, proGUI, IceDesigner
Wohnort: Bern

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von ChrigiGee »

Hallo und einen Wunderschönen Freitag @all
Hallo H. Brill,
Hallo Axolotl,

Das mit der Universal Variable, das hat mir eingeleuchtet.
Brauchte nur etwas länger als wahrscheinlich erwartet.

Wo ich mir momentan etwas den Kopf zum rauchen bring, ist die Folgende Begebenheit.

Für sich losgelöst in einer neuen Datei:

Code: Alles auswählen

If OpenFile(0,ReadMeFile$)
If ReadFile(0,ReadMeFile$,#PB_File_SharedRead )
length = Lof(0)
Bekomme ich also length als Größe der Datei sagen wir 1024

zum anderen habe ich diese Datei berechnung auch losgelöst:

Code: Alles auswählen

  If OpenPack(0, ReadMeFile_2$, #PB_PackerPlugin_Zip) 
    
    ; Listet alle Einträge auf
    If ExaminePack(0)
      While NextPackEntry(0)
      
FileLength = PackEntrySize(0, #PB_Packer_UncompressedSize)
    
        Debug "Name: " + PackEntryName(0) + ", Size: " + PackEntrySize(#PB_Any)
        Debug FileLength
Ich bekomme den Wert von FileLength mit 2048

Diese beiden Werte für sich betrachtet klappen.

Sobald ich diese in zwei Prozeduren im Kernprogramm ReadMe-VIEW
Integriere, bekomme ich entweder den einen oder den anderen.

Anzumerken ist, ich schließe beide Dateien erst am Schluss der gesamten Anwendung,
da das Schließen der einzelnen Datei in der Prozedur für sich gesehen bereits wieder WERT 0 ergibt
bei dem Main Teil der Anwendung, wo die gesamten Berechnungen zusammen kommen.

Verwende ich #PB_Any werden mir bei beiden Prozeduren Fehler ausgewiesen.
Ich muss einen klaren Wert angeben, also Test mit Prozedur 1 OpenFile(1,ReadMeFile$)
Und bei Prozedur 2 nehme ich, OpenPack(2, ReadMeFile_2$, #PB_PackerPlugin_Zip)

Ich vermutete gestern, dass sich bei Öffnen der pak Datei als OpenFile resp. OpenPak
ein Fehler ergibt.

Ich wollte versuchen, ob es möglich ist, mit nur dem Wert 2048 klarzukommen,
was nicht so erfolgreich war.

Nächster Versuch 1024 als Wert zu verbinden. Was besagte Probleme ergab.

Ohne Werte 1024 ergibt sich zudem ein Problem, bei mir,

Code: Alles auswählen

UncompressMemory(*buff1, FileLength, *buff2, FileLength, #PB_PackerPlugin_Zip)
ergibt immer 0 oder -1

FileLength = 2048 als Beispiel

Code: Alles auswählen

*buff1 = AllocateMemory(FileLength*3)
*buff2 = AllocateMemory(FileLength*6)

UnPackErg= Len( UncompressMemory(*buff1, FileLength, *buff2, FileLength, #PB_PackerPlugin_Zip))
UnPackErg= Lof( UncompressMemory(*buff1, FileLength, *buff2, FileLength, #PB_PackerPlugin_Zip))
UnPackErg= StringByteLength( UncompressMemory(*buff1, FileLength, *buff2, FileLength, #PB_PackerPlugin_Zip))
Reiner Versuch Len() und Lof() und StringByteLength() ....
Ich wollte sehen, ob eine dieser zu einem Resultat führt

Dabei ergibt sich immer ein Fehler, String erwartet.

Da bei besagten Beispielen

Code: Alles auswählen

UncompressMemory(*buff1, FileLength, *buff2, FileLength, #PB_PackerPlugin_Zip)
sowie

Code: Alles auswählen

UnPackErg= StringByteLength( UncompressMemory(*buff1, FileLength, *buff2, FileLength, #PB_PackerPlugin_Zip))
einen String Fehler ergibt, war ich auf die Idee zurückgekommen, mit dem Wert 1024 zu versuchen.
Bis gestern Abend noch nicht erfolgreich gelöst wurde.

Und wie man zusätzlich unschwer erkennt, bin ich etwas überrascht worden, dass HEUTE bereits wieder Freitag ist.

Und ich eigentlich noch immer am selber Position sitze wie letztes Wochenende.

Ich lasse mich nicht entmutigen, ich versuche den Prozess dahinter weiter aufzuschlüsseln und zu verstehen.
Auch meine Gedankenfehler Prozedur 1 und Prozedur 2 betreffend vielleicht doch überarbeitend.

Da die Zeit gegen mich arbeitet, wird das etwas schwer in wenigen Stunden hinbekommen
zu haben, und am Morgen jeweils muss ich mich gedanklich zurückversetzen, was meine Überlegungen vom Vortag waren.

Wenn die Zeit nicht immer so stark gegen einen arbeiten würde, wäre es etwas einfacher.

In diesem Sinne versuche ich den Tag so gut es geht wieder dort fortfahren zu können, wo beendet wurde.

Herzliche Grüsse
Christian

H.Brill hat geschrieben: 26.12.2024 14:10 Wenn du damit meine Bezeichnung Universalvariable meinst.
Ich meine ja nur, bei Stringvariablen (.s) kommt Text rein und in numerische Variablen (.i, .l, .q)
kommen numerische Werte rein. In so einen Speicherbereich geht alles rein. Deshalb gibt es die verschiedenen
Poke- und Peek Varianten. Auch andere Zeichen, die kein Buchstabe oder Zahl sind, funktionieren.
Bei einer Memoryvariablen kannst du auch mischen, solange du die Wertigkeit vonz.b. numerischen
Variablen(4 Bytes) beachtest. Spiel (Pb_Ascii mal weglassen) doch einfach etwas damit :

Code: Alles auswählen

zahl.l = 1250
zeile.s = "Betrag : "
length.l = Len(zeile) + 1
*buffer = AllocateMemory(50)
PokeS(*buffer, zeile, length, #PB_Ascii)
PokeL(*buffer + length, zahl)
Debug MemorySize(*buffer)
Debug PeekS(*buffer, length, #PB_Ascii)
Debug PeekL(*buffer + length)
FreeMemory(*buffer)
Wer nicht fragt, der nichts lernt.
Wer keine Fehler macht, kann sich nicht verbessern.
Das Mysterium, ein wandelndes Lexikon. :mrgreen:

Wer Fragen zu meinem Textstil hat oder sich wundert über mich,
der darf seelenruhig mich direkt ansprechen. Ich beiße noch nicht.
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von H.Brill »

PackEntrySize() gibt ja auch nur die Größe des nächsten gepackten Blocks zurück.
Das ist dann interssant, wenn du mehrere Blöcke (Dateien) ent/packen möchtest
z.b. mit einer Schleife, so etwa :

Code: Alles auswählen

*buffer = AllocateMemory(100)
If ExaminePack(0)
      While NextPackEntry(0)
        Debug "Name: " + PackEntryName(0) + ", Size: " + PackEntrySize(0)
        *buffer = ReAllocateMemory(*buffer, PackEntrySize(0))
        CatchPack(0, *buffer, MemorySize(*buffer))
        ; jetzt hast du den nächsten Speicherblock ausgelesen
      Wend
    EndIf
Bei nur einem Block bzw. einer Datei nimm besser FileSize(datei$), das dir die tatsächliche Größe
zurück gibt. datei$ ist die Datei, die du bei OpenPack() angibst. Es gibt da 2 Funktionen, die dir
die Größe einer Datei ermitteln. LOF() bei einer bereits geöffneten (OpenFile, Readfile...) und
FileSize() bei einer noch geschlossenen.

Was #PB_Any betrifft : Verwende entweder die Konstanten von z.b. Enumeration bzw. von dir vergebene
Nummern oder halt #PB_Any, aber dann auch für die folgenden abhängigen Funktionen :

Code: Alles auswählen

handle.l OpenPack(#PB_Any, ReadMeFile_2$, #PB_PackerPlugin_Zip)
If ExaminePack(handle1)
; oder hier :
handle2.l = OpenFile(#PB_Any, ReadMeFile$)
If ReadFile(handle2, ...)
  CloseFile(handle2)
EndIf
Also NICHT mischen !!!!!!!!!!!!!!!!!!!!!!!!!!!!

Der Autor Fred wollte das halt nur vereinfachen, indem er Konstanten erlaubt.
PB-intern wird das auch wieder auf Handles umgebogen, wie es halt für Windows
üblich bzw. erforderlich ist.

Hoffentlich habe ich dir nochmals etwas Licht gebracht.
PB 6.10
Axolotl
Beiträge: 266
Registriert: 31.12.2008 16:34

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von Axolotl »

Grundsätzliche Empfehlung: Ich würde den Long-Datentyp nicht generell verwenden, sondern nur dort, wo er explizit gefordert ist.
Warum? Aufgrund von internen Compilereinstellungen werden bspw. die Windows-Handle (auch Identifier genannt) jetzt auch mal größer als der Werteraum von LONG erlaubt. Wir sehen dass bei vielen alten Beispielen, die plötzlich nicht mehr funktionieren. Ausserdem ist der native Datentyp die "bessere"/sichere Variante.
Hinweis: .i (also integer) ist bei x86 32 bit und bei x64 64 bit lang.

Ich bin hier anderer Meinung, deshalb hier mal meine Sicht der Dinge:
Bei PB muss man zwischen Nummern und Handle (Identifier) unterscheiden, bzw. den Unterschied verstehen.
Generell erwarten die PB-Proceduren eine Nummer (Erkennbar an #File, #Pack, etc.). Diese Nummer muss pro Kategorie (Windows, Gadgets, Files, etc.) eindeutig sein, sonst überschreibt die letzte die vorhergehende Definition. Deshalb benutzt man (ich) gerne die Enumeration, da die Werte dann eindeutig sind.
Der Rückgabewert ist in diesen Fällen ein Wert ungleich 0 (Null), da 0 den Fehlerfall darstellt.
Möchte ich das Windows handle erhalten benutzte ich dafür die WindowID(#Window), GadgetID(#Gadger), etc. Proceduren. (Einige Proceduren geben auch das handle zurück. Ist schon seit Jahren so, steht so nur nicht in der Hilfe....muss man also für sich selbst entscheiden, ob man das so nutzen möchte)

Wenn man jetzt aber gerne #PB_Any (== -1) anstelle der eindeutigen Nummer eingibt, dann geben die o.g. Proceduren eine eindeutige Nummer zurück, mit der die weiteren Proceduren dann anstelle der #Nummer aufgerufen werden müssen. Also Rückgabewert in Variable speichern!
Da diese zurückgegebene Nummer jenseits der enumerierten Konstanten Nummern liegt ist eine Mischung beider Wege durchaus fehlerfrei möglich.

Ich möchte nicht verschweigen, das man natürlich auch direkte Zahlen für die Nummern (#Window, #Gadget, #File, #Pack, etc.) eingeben kann. Aus meiner Sicht wird das leider viel zu oft in Beispielen und der Hilfe so gemacht. Natürlich spart man damit eine Menge Schreibarbeit, allerdings wird die Pflege und die Fehlersuche in realen Projekten dadurch deutlich größer.
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von H.Brill »

Jedenfalls ist das Erstellen von Fenstern, Gadgets usw. mit den #Konstanten vom Autor von PB selbst gemacht. Ich habe bei anderen Sprachen
sowas noch nicht gesehen. Wie das Fred handelt (vlt. in einer Tabelle o. ä.) weiß ich nicht. Ob es dem Einsteiger oder sonst jemandem hilft, muß
er selber entscheiden. Ich glaube schon, daß diese 6stelligen Zahlen beim Erstellen mit #PB_Any, die richtigen Windowshandles sind. Immerhin
kann man diese ja per WindowID(), GadgetID() usw. einer API-Funktion übergeben und es funktioniert. Als Beispiel hier mal die max. Anzahl einzu-
gebender Zeichen in einem Stringgadget festlegen

Code: Alles auswählen

 
SendMessage_(GadgetID(#edit1), $00C5, 10, 0)
oder 
SendMessage_(edit1,  $00C5, 10, 0)
Und das funktioniert auch mit einer ID, die ich mit #PB_Any erhalte. Für mich deutet das auf eine eindeutige ID, die Windows beim
Erstellen vergibt, hin. Hab das mal mit XProfan gemacht. Da kommen auch 6stellige IDs raus.
PB 6.10
Axolotl
Beiträge: 266
Registriert: 31.12.2008 16:34

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von Axolotl »

Ergänzend zu meinem letzten Post, der Hilfe-Link und ein kleines Beispiel zu Handles und Nummern

Code: Alles auswählen

If OpenWindow(0, 0, 0, 322, 205, "StringGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  hGad = StringGadget(0, 8,  10, 306, 20, "0123456789")
  SendMessage_(GadgetID(0), #EM_SETLIMITTEXT, 10, 0)                ; <== Correct 

  Debug "hGad = " + Hex(hGad)
  Debug "hGad = " + Hex(GadgetID(0)) 
  Debug "" 

  Gadget = StringGadget(#PB_Any, 8,  35, 306, 20, "0123456789")
  SendMessage_(GadgetID(Gadget), #EM_SETLIMITTEXT, 10, 0)           ; <== Correct 

  Debug "Gadget = " + Hex(Gadget)
  Debug "hGad   = " + Hex(GadgetID(Gadget)) 
  Debug "" 

  Gadget2 = StringGadget(#PB_Any, 8,  60, 306, 20, "0123456789")
  SendMessage_(Gadget2, #EM_SETLIMITTEXT, 10, 0)                    ; <== ERROR 

  Debug "Gadget2 = " + Hex(Gadget2)
  Debug "hGad   = " + Hex(GadgetID(Gadget2)) 
  Debug "" 

  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
ChrigiGee
Beiträge: 125
Registriert: 18.07.2024 12:14
Computerausstattung: Lenovo ThinkPad i7, 32GB Ram, 1TB SSD
PB 6.11 LTS, proGUI, IceDesigner
Wohnort: Bern

Re: PackMemory() + Error Meldungen PB 6 oder Syntax Check (gelöst)

Beitrag von ChrigiGee »

Hallo H. Brill,
Hallo @all


Und Euch allen im Nachhinein ein Gutes Neues Jahr 2025.
Möge es so gut verlaufen, wie es gestartet ist, oder besser werden.

Vielen Dank für Deine Erläuterung. Ich glaube, ich habe langsam den Faden raus,
in diesem besagten Beispiel, ist eigentlich nur 1 Datei vorhanden, eine txt Datei.

Würde also eher Sinn ergeben, wie Du mir schilderst, über FileSize zu gehen.
Da leider etliche Zeit verstrichen ist, heißt es für mich gedanklich wieder einstimmen
auf die vorhandene Aufgabe. (Ende Dezember und Mitte Januar sind schon eher eine längere Pause)

"BabySitter" für ältere Personen ist manchmal doch anstrengender,
ich sollte es von meinem alten Herrn her noch kennen.

Das war dann bedauerlicherweise die Auszeit, welche eher etwas unfreiwillig ist.
Ich freue mich riesig, wieder daran arbeiten zu können.

Da es dann doch wieder etwas später geworden ist, heute (18 Uhr), werde ich
wohl nur noch morgen daran arbeiten können, Samstag und Sonntag bin ich
im Coffee-Shop meiner Wahl.

Grün Tee oder Mango oder Passionsfrucht Säfte, den lieben langen Tag,
und wenn Kunden hereinkommen, werde ich meistens Foto-Objekt sein.
Ausländer müssen mit den Leuten posieren.

Vielleicht am Abend, wenn man wieder zu Hause ist, kann ich mal etwas versuchen
sodass nächste Woche nicht so viel Hirn benötigt wird, um wieder zu wissen, wo man steckt.

In diesem Sinne wünsche ich Euch allen ein sehr schönes Wochenende.

Christian

H.Brill hat geschrieben: 27.12.2024 08:55 PackEntrySize() gibt ja auch nur die Größe des nächsten gepackten Blocks zurück.
Das ist dann interssant, wenn du mehrere Blöcke (Dateien) ent/packen möchtest
z.b. mit einer Schleife, so etwa :

Code: Alles auswählen

*buffer = AllocateMemory(100)
If ExaminePack(0)
      While NextPackEntry(0)
        Debug "Name: " + PackEntryName(0) + ", Size: " + PackEntrySize(0)
        *buffer = ReAllocateMemory(*buffer, PackEntrySize(0))
        CatchPack(0, *buffer, MemorySize(*buffer))
        ; jetzt hast du den nächsten Speicherblock ausgelesen
      Wend
    EndIf
Bei nur einem Block bzw. einer Datei nimm besser FileSize(datei$), das dir die tatsächliche Größe
zurück gibt. datei$ ist die Datei, die du bei OpenPack() angibst. Es gibt da 2 Funktionen, die dir
die Größe einer Datei ermitteln. LOF() bei einer bereits geöffneten (OpenFile, Readfile...) und
FileSize() bei einer noch geschlossenen.

Was #PB_Any betrifft : Verwende entweder die Konstanten von z.b. Enumeration bzw. von dir vergebene
Nummern oder halt #PB_Any, aber dann auch für die folgenden abhängigen Funktionen :

Code: Alles auswählen

handle.l OpenPack(#PB_Any, ReadMeFile_2$, #PB_PackerPlugin_Zip)
If ExaminePack(handle1)
; oder hier :
handle2.l = OpenFile(#PB_Any, ReadMeFile$)
If ReadFile(handle2, ...)
  CloseFile(handle2)
EndIf
Also NICHT mischen !!!!!!!!!!!!!!!!!!!!!!!!!!!!

Der Autor Fred wollte das halt nur vereinfachen, indem er Konstanten erlaubt.
PB-intern wird das auch wieder auf Handles umgebogen, wie es halt für Windows
üblich bzw. erforderlich ist.

Hoffentlich habe ich dir nochmals etwas Licht gebracht.
Wer nicht fragt, der nichts lernt.
Wer keine Fehler macht, kann sich nicht verbessern.
Das Mysterium, ein wandelndes Lexikon. :mrgreen:

Wer Fragen zu meinem Textstil hat oder sich wundert über mich,
der darf seelenruhig mich direkt ansprechen. Ich beiße noch nicht.
Antworten