Page 1 of 1
Passing string paramerter by reference to a procedure
Posted: Tue Nov 12, 2019 11:51 pm
by RobertRioja
How do I pass a string by reference to a procedure. In other words, how do I pass a pointer to a string so that the procedure can change the contents of the string?
I tried this but it did not work:
Code: Select all
Procedure.l GetErrorMessage(*AnErrorMessage.String)
*AnErrorMessage\s = "This is the message"
EndProcedure
S$ = " "
*Pointer.String = @S$
GetErrorMessage(*Pointer)
debug *Pointer\s
Re: Passing string paramerter by reference to a procedure
Posted: Wed Nov 13, 2019 12:00 am
by mk-soft
You need a Pointer to the Pointer of String
define Text$ is only Pointer to the String
Code: Select all
Procedure.l GetErrorMessage(*AnErrorMessage.String)
*AnErrorMessage\s = "This is the message"
EndProcedure
Define StringByRef.String
StringByRef\s = ""
GetErrorMessage(StringByRef)
Debug StringByRef\s
Structure udtText
s.s
EndStructure
Define MyErrorText.udtText
GetErrorMessage(MyErrorText)
Debug MyErrorText\s
Re: Passing string paramerter by reference to a procedure
Posted: Wed Nov 13, 2019 12:10 am
by RobertRioja
Thank you for your help. I got it to work. I was close... But you were closer.
Robert
Re: Passing string paramerter by reference to a procedure
Posted: Wed Nov 13, 2019 12:29 am
by idle
pb strings are stored in the datasection of your program which makes them a little funky
so you just need to allocate a buffer which is on the heap and it'll work as expected
Code: Select all
Procedure.i GetErrorMessage(*AnErrorMessage.string)
*AnErrorMessage\s = "This is the message"
EndProcedure
Global *StrE.String = AllocateMemory(255*SizeOf(Character))
GetErrorMessage(*StrE)
Debug *StrE\s
FreeMemory(*strE)
Re: Passing string paramerter by reference to a procedure
Posted: Wed Nov 13, 2019 8:12 am
by Lord
Why is Global for *StrE.String necessary as you provide the
adress by *StrE to the procedure?
It works without.
Re: Passing string paramerter by reference to a procedure
Posted: Wed Nov 13, 2019 7:38 pm
by mk-soft
@idle,
Your example is completely wrong and lead to the memory leak.
A pointer variable from Type String is a pointer on a pointer to the string.
After assigning a string, this then picks up the pointer to the string.
Code: Select all
Procedure.i GetErrorMessage(*AnErrorMessage.string)
*AnErrorMessage\s = "This is the message"
EndProcedure
Debug "Size Of Type String: " + SizeOf(String)
Debug "Allocate Structure Of Type String"
Global *StrE.String = AllocateStructure(string)
Debug "Act Value of Pointer to String: " + PeekI(*StrE)
Debug "Call Function..."
GetErrorMessage(*StrE)
Debug "Act Value of Pointer to String: " + PeekI(*StrE)
Debug "PeekS String over Pointer: " + PeekS(PeekI(*StrE))
Debug "Default Output: " + *StrE\s
Debug "Free Structure: Is Freed String and Memory"
FreeStructure(*strE)
Re: Passing string paramerter by reference to a procedure
Posted: Wed Nov 13, 2019 9:30 pm
by mk-soft
Small Trick
Update
Code: Select all
Macro GetVarPtr(_Var_, _Pointer_)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
lea rax, _Var_
mov _Pointer_, rax
CompilerElse
lea eax, _Var_
mov _Pointer_, eax
CompilerEndIf
DisableASM
EndMacro
Procedure.i GetErrorMessage(*AnErrorMessage.string)
*AnErrorMessage\s = "This is the message - " + *AnErrorMessage\s
EndProcedure
Define text.s, *pText
text = "Hello World"
GetVarPtr(text, *pText)
GetErrorMessage(*pText)
Debug text
Re: Passing string paramerter by reference to a procedure
Posted: Thu Nov 14, 2019 12:14 am
by nco2k
Code: Select all
Procedure.l GetErrorMessage(*AnErrorMessage)
Protected *String.String = @*AnErrorMessage
*String\s = "This is the message"
EndProcedure
S$ = " "
GetErrorMessage(@S$)
Debug S$
dunno if its safe to use though. i have no idea how pb's string builder deals with this internally.
c ya,
nco2k
Re: Passing string paramerter by reference to a procedure
Posted: Thu Nov 14, 2019 12:31 am
by mk-soft
@nco2k
that's wrong too.
You change the String at the Memory, not the Pointer to the String... Memory leak too.
Code: Select all
Procedure.l GetErrorMessage(*AnErrorMessage)
Protected *String.String = @*AnErrorMessage
*String\s = "This is the message" + *String\s
Debug *String\s ; Bad String -> Memory leak
EndProcedure
S$ = "Test "
GetErrorMessage(@S$)
Debug S$
Right Methode like API
Code: Select all
; API Methode
Procedure.i GetErrorMessage(*AnErrorMessage, MaxLen)
PokeS(*AnErrorMessage, Left("This is the message", MaxLen))
EndProcedure
text.s = Space(255)
GetErrorMessage(@text, Len(text))
Debug text
Re: Passing string paramerter by reference to a procedure
Posted: Thu Nov 14, 2019 2:03 am
by idle
thanks wasn't thinking