PDA

View Full Version : Question about thinBasic_ChangeVariableString[Direct]



ReneMiner
16-07-2013, 17:10
The goal in this simple script is to retrieve and/or change the content of a string which is passed "ByName"
I found a few functions in thinCore.inc which might make this possible- but I don't get it to work correctly :( - means it works only in 2 out of 3 runs
(Edit: Code removed, see post #4)
I already tried many constellations, so the code-fragments don't make much sense any more - thinBasic_VariableChangeStringDirect is commented since it does not work never - and I am out of ideas now.

Very strange behaviour: run again a few times. Somehow returns different results so only two of three runs work correct. To experience the changed behaviour for sure, comment/uncomment for example [ EDIT see post #4] and run again. Insert for fun a few blank lines or spaces anywhere else. But here it changes from run to run without any change in code.
Where's my bug? :unguee:

ReneMiner
20-07-2013, 07:29
Still no ideas why it does not work on strings? :unguee:

Did I use the Function in a wrong way? How would that work correct?
- is it possible or DOES thinBasic_ChangeVariableString(Direct) NOT change the StrPtr at the assigned variables name if the string length changes?
Is there maybe another function that could do this?

ReneMiner
20-07-2013, 16:43
I re-made the script so you can nicely test a few times - on numerals/fixed-size udt/array it works always. Purpose is to manipulate variables theirs names are stored in a string so a function can make use of variables with unknown pointers because they might change during execution through redim etc.
So I want to pass variables "ByName" to a function and also be able to alter their content.

Run a few times and watch the string-check. It re-runs 3 different test until you decide to press esc.
In at least 1 of 3 runs the string-content is something totally wrong but I want it to work with strings that way

It behaves frightening different if one comments line 107 and influences also strings that are passed in doublequotes while output.

Needs thinCore.inc saved next to the script


Uses "console"
#INCLUDE "thincore.inc"

Dim foo As String = "abc"
Dim dog As Ext = 1.2345678

Type t_Test
a As Long
b As Byte
c As Double
End Type

Dim oops(3) As t_Test

Dim sDummy As String = Repeat$(SizeOf(t_Test), MKBYT$(0))
Dim vDummy As t_Test At 0
Dim sResult As String

Do
PrintL $CRLF + "First test: string-variable" + $CRLF
PrintL "set to 'abc' now"
foo = "abc"

PrintL "foo is now: " + getString$("foo")
PrintL "check: " + foo

PrintL $CRLF + "change to 'test 123'"
changeString("foo", "test 123")

PrintL "foo is now: " + getString$("foo")
PrintL "check: " + foo

PrintL $CRLF + "change to 'test 2345'"
changeString("foo", "test 2345")

PrintL "foo is now: " + getString$("foo")
PrintL "check: " + foo

PrintL $CRLF + "any key" + $CRLF
WaitKey

PrintL $CRLF + "Second test: other variable" +$CRLF
PrintL "dog is now: " + CVE(getData$("dog", SizeOf(Ext)))

changeData("dog", MKE$(dog*2))
PrintL "after changeData (*2)"
PrintL "dog is now: " + CVE(getData$("dog", SizeOf(Ext)))

PrintL $CRLF + "any key" + $CRLF
WaitKey

PrintL $CRLF + "Third test: udt-array variable" + $CRLF

SetAt(vDummy, StrPtr(sDummy))
vDummy.a += 1
vDummy.b += 2
vDummy.c += 3.45

changeData("oops", sDummy, 2)


PrintL $CRLF + "after changeData:"
sResult = getData$("oops", SizeOf(t_Test), 2)

SetAt(vDummy, StrPtr(sResult))

PrintL "read oops(2).a" + Str$(vDummy.a)
PrintL "read oops(2).b" + Str$(vDummy.b)
PrintL "read oops(2).c" + Str$(vDummy.c)

PrintL $CRLF +"re-check:"
PrintL "real oops(2).a" + Str$(oops(2).a)
PrintL "real oops(2).b" + Str$(oops(2).b)
PrintL "real oops(2).c" + Str$(oops(2).c)


PrintL $CRLF + "ESC to end" + $CRLF

Loop While WaitKey <> "[ESC]"

' ---------------------------------------------------------------------------

Function getString$(ByVal sName As String, Optional Index As Long) As String

Local MainType, SubType, IsArray, DataPtr, nElements As Long

thinBasic_VariableGetInfoEX(sName, MainType, SubType, IsArray, DataPtr, nElements)
Local realPtr As DWord
' without converting to Dword it seems not to work at all
' took me a few days to find that out...
If All( _
IsArray <> 0, _
Between(Index, 1, nElements) _
) Then
realPtr = Peek(DWord, DataPtr + (Index - 1) * SizeOf(DWord))
Else
realPtr = Peek(DWord, DataPtr)
EndIf

Function = Memory_Get(realPtr, Peek(DWord, realPtr - SizeOf(DWord)))

End Function
' ---------------------------------------------------------------------------

Sub changeString(ByVal sName As String, ByVal sText As String, Optional Index As Long = 1)

Local MainType, SubType, IsArray, DataPtr, nElements As Long
'thinBasic_VariableGetInfoEX(sName, MainType, SubType, IsArray, DataPtr, nElements)

'If All( _
' IsArray <> 0, _
' Between(Index, 1, nElements) _
' ) Then
' thinBasic_ChangeVariableStringDirect(DataPtr, Index, sText)
'Else
thinBasic_changeVariableString(sName, sText) ' only non-array allowed?
'EndIf
' I tried a lot of stuff here already
' poked the result/the value at result somewhere (DataPtr) in hundred different
' ways - what's wrong here?
End Sub
' ------------------------------------------------------------------------------
Function getData$(ByVal sName As String, ByVal lSize As Long, Optional Index As Long) As String


Local MainType, SubType, IsArray, DataPtr, nElements As Long

thinBasic_VariableGetInfoEX(sName, MainType, SubType, IsArray, DataPtr, nElements)

If All( _
IsArray <> 0, _
Between(Index, 1, nElements) _
) Then
Function = Memory_Get(DataPtr + (Index - 1) * lSize, lSize)
Else
Function = Memory_Get(DataPtr, lSize)
EndIf

End Function
' ------------------------------------------------------------------------------
Sub changeData(ByVal sName As String, ByVal sData As String, Optional Index As Long)

Local MainType, SubType, IsArray, DataPtr, nElements As Long

thinBasic_VariableGetInfoEX(sName, MainType, SubType, IsArray, DataPtr, nElements)
If All( _
IsArray <> 0, _
Between(Index, 1, nElements), _
sData <> "" _
) Then

Memory_Set(DataPtr + (Index - 1) * Peek(DWord, StrPtr(sData) - 4), sData)

ElseIf sData <> "" Then
Memory_Set(DataPtr, sData)
EndIf

End Sub

ReneMiner
20-07-2013, 18:34
Not directly, one could use dictionary or LL for that i think. But your sub "knows" the variables name not through a passed parameter.

Does it do this:


uses "console"

Dim oops(3) as Long
Dim test as String

SetVar("oops", Mkl$(123), 2)
PrintL CVL(GetVar("oops", SizeOf(Long), 2)) ' equal output as PrintL oops(2)

SetStr("test", "hello John")
PrintL GetStr("test") ' equal output as PrintL test

WaitKey

Sub SetVar(ByVal sName as String, Byval NewVal as String, Optional Index as Long)

???
End Sub

Function GetVar(ByVal sName as String, ByVal lSize as Long, Optional Index as Long) As String

???
End Function


Output:
123
hello John
?

ReneMiner
20-07-2013, 19:09
but the problem is- (it's the same example as you posted above) - your sub "knows" the expression "myvar" - my listboxes/trees & grids don't know which array or whatever user assigned to them to be displayed. If user assigns them once on startup and they change, the pointers change also- so it makes no sense to store their pointers.
But if user tells: my phone-list to display in this listview is stored to variable "xy" - my listview -or whatever- knows where to get the actual current data and possibly also the amount of.
Problem in tB is just that I can't get valid pointers from plain String/String-Array- no problem if UDT here even with strings inside - their pointers are correct
the other problem is that I can not change the value of any string somehow - a few times it works but not always :( - so my grid, listview- whatever-content is not editable

Edit: Even if not an expression- it's not a keyword but becomes some array through those curly braces. Won't help if the function does not know the name of the array since the function is supposed to "live" in an unit-file or maybe even a module.

Petr Schreiber
21-07-2013, 09:10
Hi Rene,

when testing on my PC, and using thinDebug to step through, it seems to me in getString$ I get realPtr equal to zero, which, of course, causes GPF on PEEKing.
I also get zero for all the parameters retrieved via thinBasic_VariableGetInfoEX, which is strange.

I think the main issue is the inception issue :) - calling these functions from thinBasic itself, I think it creates some kind of clash.
I would recommend to create this in form of DLL module.


Petr

ReneMiner
21-07-2013, 09:19
If I run the script in debug mode thinBasic crashes.

Petr Schreiber
21-07-2013, 09:21
For me it crashes both ways - on the same place, during execution of line 25 (with thinBasic 1.9.7.0).
As I said, I think thinCore is probably not ready to be used from within script, as it seems to cause some kind of interference.


Petr

ReneMiner
21-07-2013, 09:39
:unguee:

- thats really strange. on my pc (also tB 1.9.7) it only crashes in debug-mode. In "F5-mode" it runs and runs and runs as long as I want it to but in 1 out of 3 cases I get wrong results for the strings and if the sub changeString does not have local variables the console-printout gets messed up so


PrintL "foo is now: " + getString$("foo")
PrintL "check: " + foo

PrintL $CRLF + "change to 'test 123'"
changeString("foo", "test 123")

PrintL "foo is now: " + getString$("foo")
PrintL "check: " + foo


prints out like:

foo is now: abc
check : abc

change to 'test 123'
DATAPTR test 123
check : FOO

-so would it be a way around if using thinCore.inc through oxygen?