Seite 2 von 3

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 11:44
von Josh
Hast du meinen letzten Beitrag bis zum Ende gelesen? Dann hast du deine 48 Byte.

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 11:56
von NicTheQuick
Etwas umständlicher, aber so geht's auch:

Code: Alles auswählen

Structure strBHC_Header
	sMagicWord.a[4]
	wDatabaseType.w
	sUserdefinedDatabaseTypecode.a[8]
	lVersion.l
	sDescription.a[30]
EndStructure

Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode

Define bhc.strBHC_Header

; Schreiben
PokeS(@bhc\sDescription, "Hallo", 30, #PB_Ascii)

; Lesen
Debug PeekS(@bhc\sDescription, 30, #PB_Ascii)

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 18:45
von Sicro
@NicTheQuick:
Unsere Codes sind sehr ähnlich :mrgreen:
Ich habe gar nicht gewusst, dass man die eckigen Klammern "[0]" später auch weglassen kann.

@Kurzer:
Vermutlich weißt du das schon, aber mit den Codes von NicTheQuick und mir, kannst du die Struktur ganz einfach in einem Rutsch von einer Datei einlesen oder in eine Datei schreiben:

Code: Alles auswählen

WriteData(File, @Header, SizeOf(strBHC_Header))
ReadData(File, @Header, SizeOf(strBHC_Header))

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 19:31
von Kurzer
Es gibt ja dann doch so einige Ansätze wie man das lösen kann.
Vielen Dank für Eure Vorschläge. <)

@Josh: Ja, ich habe den Teil gelesen. "sDescription.s{30/SizeOf(Character)}" ist eine andere Schreibweise wie für "sDescription.a[30]". Es kommen halt in beiden Fällen immer 30 Byte Platz bei raus.

Allerdings muss man auch in Deinem Fall auf Peek und Poke für das Lesen und Schreiben zurückgreifen.
Ich überlege noch was für mich am optimalsten ist. Die gesamte Struktur mit einem WriteData() zu schreiben hat seinen Reiz. Beim Einlesen jedoch lese ich die Felder einzeln ein, um sie vor dem endgültigen Laden der Datei einer logischen Prüfung zu unterziehen.

Ich kann auch eine zweite Version der Struktur definieren, die dann entsprechend mit ".a[30]" arbeitet statt mir ".s[30]" und diese Struktur ausschließlich für die Größenermittlung per SizeOf() nutzen.

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 19:57
von NicTheQuick
Ich würde die Struktur nicht Stück für Stück einlesen, sondern an einem Stück. Ob die Daten Sinn ergeben, kannst du später immer noch überprüfen. Der Vorteil einer festen Strukturgröße ist ja, dass du sie am Stück und damit sehr schnell einlesen kannst. Und wenn du davor die Strukturgröße in die Datei schreibst, dann weißt du auch, dass es passen muss.

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 20:24
von mk-soft
Habe mal zwei Macros geschrieben um vereinfacht ASCII Arrays zu lesen und zu schreiben,
und die Sache mit WriteData und ReadData...

Code: Alles auswählen

Structure strBHC_Header
   sMagicWord.a[4]
   wDatabaseType.w
   sUserdefinedDatabaseTypecode.a[8]
   lVersion.l
   sDescription.a[30]
EndStructure

Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode

Global bhc.strBHC_Header
Global bhc2.strBHC_Header

Macro SetA(Destination, Text)
  PokeS(@Destination, Text, SizeOf(Destination), #PB_Ascii)
EndMacro

Macro GetA(Source)
  PeekS(@Source, SizeOf(Source), #PB_Ascii)
EndMacro

Debug SizeOf(bhc\sMagicWord)

; Schreiben
SetA(bhc\sMagicWord, "12345678")
SetA(bhc\sDescription, "Hallo")

If CreateFile(0, GetHomeDirectory() + "TestData.bin")
  Debug "Save datablock"
  WriteData(0, bhc, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

; Lesen
If ReadFile(0, GetHomeDirectory() + "TestData.bin")
  Debug "Read datablock"
  ReadData(0, bhc2, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

Debug GetA(bhc2\sMagicWord)
Debug GetA(bhc2\sDescription)

CallDebugger

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 20:41
von Kurzer
@NicTheQuick: Ja, ich geb Dir Recht.

Bei meinen Tests bin ich auch auf den neu eingeführten Befehl Ascii($Text) gestoßen, aber so ganz versteh ich nicht was der anders macht, als z.B. ein entsprechendes PokeS(... #PB_Ascii). Ist leider nur aufwändiger mit Ascii().

Code: Alles auswählen

Structure Struct
	sText.s{6 / SizeOf(Character)}
EndStructure

Global Test.Struct

; Version mit Poke...
PokeS(@Test\sText, "Hallo!", 6, #PB_Ascii)

ShowMemoryViewer(@Test\sText, 100)
CallDebugger

; Version mit Ascii()...
*mem = Ascii("012345")
CopyMemory(*mem, @Test\sText, 6)
FreeMemory(*mem)

ShowMemoryViewer(@Test\sText, 100)
CallDebugger

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 20:51
von Kurzer
mk-soft hat geschrieben:Habe mal zwei Macros geschrieben um vereinfacht ASCII Arrays zu lesen und zu schreiben,
und die Sache mit WriteData und ReadData...
Danke für Deine Mühe. Das funktioniert aber offenbar nicht mehr, wenn man als Strukturvariable eine Pointervariable nutzt. Ich nutze ja Deine OOP-BaseClass für dieses Projekt und die Referenzierung der Strukturen beginnt damit immer mit "*this\..."

Damit klappt das nicht mehr. Das kannst Du prüfen indem Du in Deinem Code aus der Strukturvariable "bhc2" ein "*bhc2" machst.

Code: Alles auswählen

Structure strBHC_Header
   sMagicWord.a[4]
   wDatabaseType.w
   sUserdefinedDatabaseTypecode.a[8]
   lVersion.l
   sDescription.a[30]
EndStructure

Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode

Global bhc.strBHC_Header
Global *bhc2.strBHC_Header

Macro SetA(Destination, Text)
  PokeS(@Destination, Text, SizeOf(Destination), #PB_Ascii)
EndMacro

Macro GetA(Source)
  PeekS(@Source, SizeOf(Source), #PB_Ascii)
EndMacro

Debug SizeOf(bhc\sMagicWord)

; Schreiben
SetA(bhc\sMagicWord, "1234")
SetA(bhc\sDescription, "Hallo")

If CreateFile(0, "D:\TestData.bin")
  Debug "Save datablock"
  WriteData(0, bhc, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

; Lesen
If ReadFile(0, "D:\TestData.bin")
  Debug "Read datablock"
  ReadData(0, *bhc2, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf

Debug GetA(*bhc2\sMagicWord)
Debug GetA(*bhc2\sDescription)

CallDebugger

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 21:30
von Sicro
@Kurzer:

Der neue Befehl Ascii() (gibt auch noch UTF8() ) macht intern nichts anderes als das:

Code: Alles auswählen

Procedure.i Ascii2(String$)
  Protected NeededMemorySize, *Memory
  
  NeededMemorySize = StringByteLength(String$, #PB_Ascii)
  NeededMemorySize + 1 ; For the null-character on the end of the string (ascii/utf8: 1 byte, unicode: 2 bytes)
  *Memory = AllocateMemory(NeededMemorySize)
  If *Memory
    PokeS(*Memory, String$, -1, #PB_Ascii)
  EndIf
  
  ProcedureReturn *Memory
EndProcedure
Der Befehl ist also ein Kürzel für obigen Code.

Bei meinem vorherigem Code habe ich einen Fehler gemacht. PokeS() schreibt noch das Null-Zeichen hinter den String.

Code: Alles auswählen

; Schreiben
PokeS(@Header\sMagicWord[0], "ABCD", -1, #PB_Ascii)
ersetzen durch:

Code: Alles auswählen

; Schreiben
PokeS(@Header\sMagicWord[0], "ABCD", -1, #PB_Ascii | #PB_String_NoZero)
Andernfalls schreibt PokeS() in diesem Fall in wDatabaseType.w rein, wenn du bei sMagicWord.a[4] alle 4 Zeichenplätze voll schreibst.

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel

Verfasst: 24.01.2018 22:02
von mk-soft
Kurzer hat geschrieben: Damit klappt das nicht mehr. Das kannst Du prüfen indem Du in Deinem Code aus der Strukturvariable "bhc2" ein "*bhc2" machst.
*bhc2 ist ja nur ein Pointer auf eine Speichergebiet. Wenn Du keinen Speicher anforderst geht das natürlich nicht

Code: Alles auswählen

*bhc2 = AllocateStructure(strBHC_Header)
; Lesen
If ReadFile(0, "D:\TestData.bin")
  Debug "Read datablock"
  ReadData(0, *bhc2, SizeOf(strBHC_Header))
  CloseFile(0)
EndIf
P.S.
In den Modul BaseClass wird ja bei anlegen eines Objektes Speicher angelegt.
Ist allerdings in der Struktur wieder ein Pointer definiert, so muss beim Initialisieren (AsInitializeObject) selber dieser Speicher angefordert werden
und beim Objekt freigeben (AsDisposeObjekt) wieder freigegeben werden.
Kann ja mal ein Beispiel schreiben...