View Full Version : disturbs me for a long time already...
ReneMiner
31-10-2014, 10:02
it's the impossibility to pass udt-elements ByRef, thinBasic will not accept these,
see here:
Uses "console"
Function f_byref(ByRef lLong As Long) As Long
Function = lLong
End Function
Dim bac As Long = 12345 ' normal variable no problemo
PrintL Str$( f_ByRef( bac ) )
WaitKey
Type t_Test
abc As Long
End Type
Dim foo As t_Test
foo.abc = 123 ' but udt-element gets refused as parameter
PrintL Str$( f_ByRef( foo.abc ) )
WaitKey
ByRef is of no use for udt-elements, it's not possible to pass them as function-parameters by reference directly
one always has to do something like this to pass them byRef:
Uses "console"
' either pass a pointer and create a layover in the function:
Function f_byPtr( ByVal pLong As DWord ) As Long
Local lLong As Long At pLong
Function = lLong
End Function
Type t_Test
abc As Long
End Type
Dim foo As t_Test
foo.abc = 54321
PrintL Str$( f_ByPtr( VarPtr foo.abc ) )
WaitKey
' or create layover in advance:
Function f_byref(ByRef lLong As Long) As Long
Function = lLong
End Function
Dim toPass as Long At VarPtr(foo.abc)
PrintL Str$( f_ByRef( toPass ) )
WaitKey
Best would be if udt-elements would be accepted using normal syntax (Byref).
If that's not possible - however..., why..., i don't care the reason... it could be substituted using ByPtr. Means
Function myFunc(ByPtr lVar As someType )
the function automatc creates a local layover lVar As someType At passed pointer.
ByPtr of course awaits a pointer passed ByVal then. It would additionally enable automatic layover at some heap or StrPtr.
But i would be satisfied already if i could just pass the UDT-element ByRef.
ErosOlmi
31-10-2014, 12:48
Thanks for remembering this limitation.
I will work on it during the week-end and see what I can do. Should be easy but not sure.
You can pass the whole UDT as ByRef if you need it in the meanwhile.
PS: I'm also working on this:
string variadic parameterer (already developed)
dynamic arrays inside UDT including REDIM [Preserve] ... possibility.
ErosOlmi
10-11-2014, 09:40
Attached an updated version of thinCore.dll for testing.
For every variable defined in a script, ThinBASIC maintain a complex variable structure used for internal purposes.
So far when using BYREF ina function parameter, thinBasic was passing a reference to that variable instead of a simple pointer to the memory area of the passed data.
This was to reduce possible GPF and for other interesting possibilities.
I admit that this method is, from one side very useful for me but on the other side very limiting. For example elements of UDT do not have such an internal structure but have another one, more complex. Keeping all together is starting to be a nightmare.
So I've started to switch to a more "standard" way of handling BYREF that is passing a direct data pointer instead of a pointer to the internal variable structure.
I started from numeric variable and standard functions (not yet UDT functions)
I should have added BYREF for numeric.
Let me know, in the meantime I will go on changing the rest of the code.
Ciao
Eros
ReneMiner
10-11-2014, 09:55
first usage-test looks good :D
Uses "console"
Uses "TBGL" ' for the color-type
Function fTestRed(ByRef lColor As Byte)
PrintL lColor
End Function
Function fTestGreen(ByRef lColor As Byte)
PrintL lColor
End Function
Function fTestBlue(ByRef lColor As Byte)
PrintL lColor
End Function
Dim myColor As TBGL_TRGB
myColor.R = 1
myColor.G = 2
myColor.B = 3
fTestRed( myColor.R )
fTestGreen( myColor.G )
fTestBlue( myColor.B )
PrintL $CRLF & "----------------------------------> any key to end"
WaitKey
Edit:
could not resist to try out strings... at least we have some testscript already:
Uses "console"
Function StrAt(ByRef s As String) As String
Local p As DWord At VarPtr(s)
If p Then Function = Memory_Get(p, Peek(DWord, p - 4))
End Function
Type t_testtype
s As String
End Type
Dim sTest As String = "we test simple string"
PrintL StrAt( sTest )
$aConst = "constants seem to work too..."
PrintL StrAt( $aConst )
Dim foo As t_testtype
foo.s = "we test succesful udt"
PrintL StrAt( foo.s )
PrintL $CRLF & "----------------------------------> any key to end"
WaitKey
++ Edit one more since now it's possible - but kind'a off-topic:
To explain, thinBasic allows very much heavy usage of string-content to control program flow, For example "Call_IfExists", "Dialog New Name", "Dim ... Like" etc.
All the Strings like dialogs names, function-names-components, "_mouse", "_click", "_wheel" whatever- have to be stored once only but not to each and every object.
Currently I use for this Heap-memory, store each string once, assign only the pointer to the objects and use Heap_Get(object.hPtr) to read it out.
For a more common usage and people who like to prefer strings to store string-data it would be adequate to have some similar easy way of assigning the same string-text-content to multiple objects without having to store a string twice- that brings us to $StringConstants .
Now currently:
' there would be a long list of styles, events, f.e.
$CS_Window = "Window"
' some control-style be "Window"
' the pointer to that const is a unique number that gets assigned to some .Style-property (DWord)
' of an imaginary t_Control-udt now
Dim Ctrl(123) As t_Control
Ctrl(1).Style = StrPtr($CS_Window)
' and now we can pass this t_Control.Style-Dword BYREF to read its String-content out -
' so it does not create additional variables here
' as well as to identify the style without comparing strings
' because it's globally the same number to all of these "Window"s
' btw. assures all Ctrl()-members have the same fixed size for this property
' somehow then it comes to something like that:
If lEvent Then
Call_IfExists "" & StrAtPtr$( Ctrl(current).Style ) & StrAtPtr$( lEvent )
EndIf
and that's why i would like to suggest it (again?) since it works on udts too now, below contained simple function StrAtPtr$ which returns the String from a pointer
Function StrAtPtr$(ByRef p As DWord) As String
' returns string at p - assumed p is a valid StrPtr
If p Then Function = Memory_Get(p, Peek(DWord, p - 4))
End Function
' ##################################
' other usage: 2 ways...
Uses "console", "dictionary"
DWord mydict = Dictionary_Create(100)
' DWord myPtr = <uncomment and pull code below up>
Dictionary_Add(myDict, "test", "I am some important string")
Dim myPtr As DWord At Dictionary_Exists(myDict, "test") ' < comment this line then >
PrintL "Dictionary content at myPtr :"
PrintL StrAtPtr$(myPtr)
WaitKey
ReneMiner
10-11-2014, 22:23
more of this :)
You know it makes no sense and that's why is not possible to
Dim s As String At somePointer
because dynamic string is kind'a different
- but what if "somePointer" is a valid StrPtr...? Wouldn't this make sense?
Special of this layover-interpretation ( it were none, thinCore has to Dim s as real string with the pointed content ) so it would be automatical that these "virtual dynamic strings" are read-only by default because it's not possible to change the real data.
Which brings us to protected variables...
ReneMiner
15-11-2014, 11:00
another testscript if udt-sub-strings would work ByRef we could shorten
String sText = "hello 123"
Long theNumberWeSearch = StrPtrLen(StrPtr(sText))
to something like
Long theNumberWeSearch = StrLen(sText)
testscript (non-functional currently)
Uses "console"
Function StrLen( ByRef s As String ) As DWord
Local Result As DWord At StrPtr(s)-4
Return Result
End Function
String test1 = "hello we test"
PrintL "StrLen(test1) = " & StrLen(test1)
Type t_test
s As String
End Type
Dim foo As t_test
foo.s = "123456789"
PrintL "StrLen(foo.s) = " & StrLen(foo.s)
WaitKey