Dim filbuff As Any Ptr
Type hdrtyp1 Field = 1
As ULong sig
As UByte typ
As UByte ignore1
As UShort ignore2
As UShort modid
As UShort modsiz
As Integer cksm
As ULongInt modver
End Type
Dim hdr_royl As hdrtyp1
Dim filbuff As Any Ptr
Type hdrtyp1 Field = 1
As ULong sig
As UByte typ
As UByte ignore1
As UShort ignore2
As UShort modid
As UShort modsiz
As Integer cksm
As ULongInt modver
End Type
'get some data
dim as hdrtyp1 T(1 to 3)
T(1).sig=10001
T(2).sig=10002
T(3).sig=10003
filbuff=@T(1)
Dim hdr_royl As hdrtyp1
for n as long=0 to 2
hdr_royl=cast(hdrtyp1 ptr,filbuff)[n]
print hdr_royl.sig
next n
sleep
Be a little more specific in your question (so that we can answer you precisely):
- do you want to create a new 'hdrtyp1' object, and to initialize it from the RAM buffer values?
Note: As 'filbuff' is an 'Any Ptr', 'filbuff[n]' and also '@filbuff[n]' are not valid (by cons the address 'filbuff + n' is valid).
Dim filbuff As Any Ptr
Type hdrtyp1 Field = 1
As ULong sig
As UByte typ
As UByte ignore1
As UShort ignore2
As UShort modid
As UShort modsiz
As Integer cksm
As ULongInt modver
End Type
'get some data
dim as hdrtyp1 T(1 to 3)
T(1).sig=10001
T(2).sig=10002
T(3).sig=10003
filbuff=@T(1)
Dim hdr_royl As hdrtyp1 ptr
hdr_royl=filbuff
for n as long=0 to 2
print hdr_royl[n].sig
next n
sleep
ISTM that this task is unnecessarily complicated, even convoluted. By comparison, if I want to Get a UDT using file I/O, I simply specify the UDT variable, and the byte offset within the file. I was hoping that RAM I/O could be done in an analogous way. That is, specify the byte offset in memory using Any Ptr, and then read/write the appropriate amount of data by matching it to the variable type. Isn't that the more logical way to go about this task?
' static initialized type (for this DEMO only!)
Type UDT_t ' size FBC64 = 32, FBC32 = 20
As ULong id = 1
As ULong slen = 4
As String info = "test"
End Type
Type pUDT As UDT_t Ptr ' type ptr alias (aka: forward declaration)
' end type
' methods to acess the members of a type
Dim As UDT_t my1 ' for direct 'type.member' access
Dim As pUDT pmy1 = @my1 ' for indirect 'type_ptr->member' access
Print "type size "; Str(SizeOf(UDT_t))
Print
Print "type.member access"
Print "id "; my1.id
Print "slen "; my1.slen
Print "info "; my1.info
Print
Print "type_ptr->member access"
Print "id "; pmy1->id
Print "slen "; pmy1->slen
Print "info "; pmy1->info
Sleep
One other annoyance is the way that UDTs handle strings. There are many times when I wish to Get a binary String which contains 0x00 characters. This works OK for String variables on their own, but I have trouble when these Strings (or WStrings or Zstrings) are members of a UDT. Is there any way to specify a UDT where the member strings are not terminated by zeros, and where zeros can be part of the string itself?
Type hdrtyp1 Field = 1
As ULong sig
As UByte typ
As UByte ignore1
As UShort ignore2
As UShort modid
As UShort modsiz
As Integer cksm
As ULongInt modver
End Type
function show(p as any ptr,n as long) as double
dim as integer i=cint(p)
select case n
case 1
return (*cast(ulong ptr,i))
case 2
i+=4
return (*cast(ubyte ptr,i))
case 3
i+= 1+4
return (*cast(ubyte ptr,i))
case 4
i+= 1+1+4
return (*cast(ushort ptr,i))
case 5
i+= 2+1+1+4
return (*cast(ushort ptr,i))
case 6
i+= 2+ 2+1+1+4
return (*cast(ushort ptr,i))
case 7
i+=2+2+ 2+1+1+4
return (*cast(integer ptr,i))
case 8
i+=sizeof(integer)+2+2+ 2+1+1+4
return (*cast(ulongint ptr,i))
end select
end function
'get some data
dim as hdrtyp1 T
with T
.sig=1
.typ=2
.ignore1=3
.ignore2=4
.modid=5
.modsiz=6
.cksm=-7
.modver=8
end with
Dim filbuff As Any Ptr=@T
for n as long=1 to 8
print show(filbuff,n)
next
sleep
fzabkar wrote:There are many times when I wish to Get a binary String which contains 0x00 characters.
FB's String (a type in fact) is the only one that allowes Chr(0) inside the string data (also Null terminated).
ZString and/or WString cannot accept Chr(0) because it is treated as terminator.
type udt
as ubyte u(100)
dim as long n
declare constructor
declare constructor(as string)
declare operator cast() as string
end type
constructor udt
'Hi!
end constructor
constructor udt(s as string)
n=len(s)-1
for m as long=0 to n
u(m)=s[m]
next m
end constructor
operator udt.cast() as string
dim as string s
for m as long=0 to n
s+=chr(u(m))
next m
return s
end operator
dim as udt u=any
u=udt("FreeBASIC"+chr(0)+"..."+chr(0))
print "'";u;"'"
sleep
Many thanks. There are quite a few concepts I need to get my head around.
At present I'm revisiting my old programs and fixing some of the ugly coding. I'll probably end up writing code that is less efficient, but which I find easiest to comprehend. I expect I'll have a lot more questions along the way.