Page 1 of 1
Allow to change a structure of a pointer
Posted: Fri Jan 20, 2012 2:27 pm
by infratec
Hi,
it would be nice if something like this is possible:
Code: Select all
If Type = 1
*ptr.Type1Str = *Buffer
else
*ptr.Type2Str = *Buffer
endif
Bernd
Re: Allow to change a structure of a pointer
Posted: Fri Jan 20, 2012 4:22 pm
by ts-soft
This is possible
//edit
not to create a structure at runtime, but to use different structures
Re: Allow to change a structure of a pointer
Posted: Fri Jan 20, 2012 4:29 pm
by Fred
Well, if you can change the structure at runtime, how will you access the fields if the structure have different fiels ? It needs to known at compile time, as PB isn't an interpreted language.
Re: Allow to change a structure of a pointer
Posted: Fri Jan 20, 2012 4:42 pm
by STARGĂ…TE
use structure union:
Code: Select all
Structure BothTypes
StructureUnion
Type1.Type1Str
Type2.Type2Str
EndStructureUnion
EndStructure
*ptr.BothTypes = *Buffer
If Type = 1
*ptr\Type1\...
Else
*ptr\Type2\...
EndIf
Re: Allow to change a structure of a pointer
Posted: Fri Jan 20, 2012 7:05 pm
by infratec
@Stargate
That's clear, but not what I need.
In your case I have to use the whole time a different name to access the structure.
At the moment I solve it this way:
Code: Select all
If ChannelRecordSize = 100
ReadChannel.Prototype_ReadChannel = @ReadChannel100()
ElseIf ChannelRecordSize = 476
ReadChannel.Prototype_ReadChannel = @ReadChannel476()
EndIf
Than I can call the 'same' procedure:
ReadChannel(*Buffer + Ptr) for the rest of the program
But I need 2 procedures which are completely identical up to the structure which I use for the pointer:
Code: Select all
Procedure ReadChannel100(*Channel.Channel100Str)
Code: Select all
Procedure ReadChannel476(*Channel.Channel476Str)
Bernd
Re: Allow to change a structure of a pointer
Posted: Fri Jan 20, 2012 9:26 pm
by helpy
Hi,
I do not see any way to do this in PureBasic, if both structures are completely different.
If both structures are extended from a base structure and the procedure only uses the base elements, you could do the following:
Code: Select all
Structure ChannelBase
; base elements
EndStructure
Structure Channel100Str Extends ChannelBase
; 100Str specific elements
EndStructure
Structure Channel476Str Extends ChannelBase
; 476Str specific elements
EndStructure
Procedure ReadChannel( *Channel.ChannelBase )
; ....
EndProcedure
; ....
ReadChannel( *ptr100Str )
; ....
ReadChannel( *ptr476Str )
; ....
After all there maybe is a way ... hmmm ....
You could create a standardized structure and COPY all elements from the original structure to the standardized one, which is handled by the Procedure ReadChannel(*Channel.ChannelStandardized).
cu,
guido
Re: Allow to change a structure of a pointer
Posted: Sat Jan 21, 2012 8:25 am
by breeze4me
I think anonymous structure union will be more useful.
Something like this.
Code: Select all
Structure BothTypes
StructureUnion
AnonymousStructure Type1Str
AnonymousStructure Type2Str
EndStructureUnion
EndStructure
*ptr.BothTypes = *Buffer
or
Code: Select all
Structure BothTypes
StructureUnion
AnonymousStructure ;Type1Str
......
EndAnonymousStructure
AnonymousStructure ;Type2Str
......
EndAnonymousStructure
EndStructureUnion
EndStructure
Edit:
Never mind.
This way has a problem.
Re: Allow to change a structure of a pointer
Posted: Sat Jan 21, 2012 9:14 am
by Trond
infratec wrote:But I need 2 procedures which are completely identical up to the structure which I use for the pointer:
Code: Select all
Procedure ReadChannel100(*Channel.Channel100Str)
Code: Select all
Procedure ReadChannel476(*Channel.Channel476Str)
Bernd
If what you say is true (the procedures are actually, truly, identical) then, by definition, one structure must be a subset of the other, else field lookup wouldn't work. In this case, just pass in the address of the variable + the offset in the structure where the subset starts, and it will work regardless of declared structure.
It would help if you showed us the structures.
If you want runtime duck typing then make your structure contain a single map and shove all your members in there.
Re: Allow to change a structure of a pointer
Posted: Sat Jan 21, 2012 4:16 pm
by infratec
Hi Trond,
Here is what you want:
Code: Select all
Structure Channel100Str
Name.s{32}
Dummy0.a[12]
Transponder.a
Dummy1.a[15]
ServiceID.u
EndStructure
Structure Channel476Str
Name.s{32}
Dummy0.a[12]
Transponder.a
Dummy1.a[391]
ServiceID.u
EndStructure
Prototype Prototype_ReadChannel(*Channel)
Global ReadChannel.Prototype_ReadChannel
Procedure ReadChannel100(*Channel.Channel100Str)
Channel$ = *Channel\Name + #LF$
Channel$ + Str(*Channel\Transponder) + #LF$
Channel$ + Str(*Channel\ServiceID)
AddGadgetItem(0, -1, Channel$)
EndProcedure
Procedure ReadChannel476(*Channel.Channel476Str)
Channel$ = *Channel\Name + #LF$
Channel$ + Str(*Channel\Transponder) + #LF$
Channel$ + Str(*Channel\ServiceID)
AddGadgetItem(0, -1, Channel$)
EndProcedure
Depending on the 'version' of the file which I process, I use one or the other:
Code: Select all
:
:
:
If ChannelRecordSize = 100
ReadChannel.Prototype_ReadChannel = @ReadChannel100()
ElseIf ChannelRecordSize = 476
ReadChannel.Prototype_ReadChannel = @ReadChannel476()
EndIf
ClearGadgetItems(0)
For i = 1 To Channels
ReadChannel(*Buffer + Ptr)
Ptr + ChannelRecordSize
Next i
:
:
:
My solution works, but it's 'ugly'.
Bernd
Re: Allow to change a structure of a pointer
Posted: Sat Jan 21, 2012 5:47 pm
by Trond
If it's coming from somewhere, the format is fixed and you can't do much about it.
But If you can swap the two last fields in both structures, or make both structures extend from one, with the field Dummy1 as the only field in each used structure, this can be solved elegantly:
Code: Select all
Structure ChannelStr
Name.s{32}
Dummy0.a[12]
Transponder.a
ServiceID.u
Dummy1_.a[0]
EndStructure
Structure Channel100Str Extends ChannelStr
Dummy1.a[15]
EndStructure
Structure Channel476Str Extends ChannelStr
Dummy1.a[391]
EndStructure
Procedure ReadChannel(*Channel.ChannelStr)
Channel$ = *Channel\Name + #LF$
Channel$ + Str(*Channel\Transponder) + #LF$
Channel$ + Str(*Channel\ServiceID)
AddGadgetItem(0, -1, Channel$)
EndProcedure
ClearGadgetItems(0)
For i = 1 To Channels
ReadChannel(*Buffer + Ptr)
Ptr + ChannelRecordSize
Next i
Re: Allow to change a structure of a pointer
Posted: Sat Jan 21, 2012 6:25 pm
by skywalk
Trond wrote:
Code: Select all
Structure ChannelStr
Name.s{32}
Dummy0.a[12]
Transponder.a
ServiceID.u
;
Dummy1_.a[0] ;<-- If you omit this, I assume the code will fail?
;
EndStructure
Structure Channel100Str Extends ChannelStr
Dummy1.a[15]
EndStructure
Structure Channel476Str Extends ChannelStr
Dummy1.a[391]
EndStructure
Nice.

I noticed this behavior a while back and thought it was a mistake.
Even though you don't reference the extended structure, the fields are there for the taking.