[Resolved] Call procedure with several parameters by name

Just starting out? Need help? Post your questions and find answers here.
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Call procedure with several parameters by name

Post by chi »

Kwai chang caine wrote:And i don't understand why...i have an error when the array is freeing :shock:
Apart from a little typo (you wrote: MaxParam = CountString(Parametre$, ",") and not Parameter$) and the fact that arrays start with 0 (why allocate an empty element?), your example works perfectly fine with PB x64 but crashes with PB x86 because the ArraySize returns -1 after the first Call(ArrayParams(0))
I'd call this a bug :!:

Code: Select all

Prototype AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")

Runtime Procedure MessageOneParameter(Text.s)
  MessageRequester("Only one Parameter", Text)
EndProcedure

Runtime Procedure MessageTwoParameters(Text1.s, Text2.s)
  MessageRequester("Two parameters", Text1 + Text2)
EndProcedure

Runtime Procedure MessageThreeParameters(Text1.s, Text2.s, Text3.s)
  MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure

Procedure CallProcedure(NomProcedure.s, Parameter$)
  
  *PtrProc = GetRuntimeInteger(NomProcedure + "()")
  Call.AllMessages = *PtrProc
  MaxParam = CountString(Parameter$, ",") 
  Protected Dim ArrayParams.s(MaxParam)

  For i = 0 To MaxParam
    ArrayParams(i) = StringField(Parameter$, i+1, ",")
  Next
  
  Debug "Pre Call Size = " + ArraySize(ArrayParams()) 
  
  Select MaxParam
    Case 0
      Call(ArrayParams(0))
    Case 1
      Call(ArrayParams(0), ArrayParams(1))
    Case 2
      Call(ArrayParams(0), ArrayParams(1), ArrayParams(2))
  EndSelect
  
  Debug "Post Call Size = " + ArraySize(ArrayParams()) 
  Debug "------------------"
  
  FreeArray(ArrayParams())
  
EndProcedure

CallProcedure("MessageOneParameter", "Hello it's KCC")
CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
[/size]
Et cetera is my worst enemy
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Call procedure with several parameters by name

Post by Kwai chang caine »

Hello THE.WEAVSTER :D
Thanks for your code, with it it's really more simple to manage parameters 8)
Chi wrote:your example works perfectly fine with PB x64 but crashes with PB x86
Hello CHI :D
You have totaly right, i have download and compile in x64 for see, and me too that works in X64 :shock:
Pre Call Size = -1
Post Call Size = -1
------------------
Pre Call Size = 1
Post Call Size = -1
------------------
Pre Call Size = 2
Post Call Size = -1
------------------
Pre Call Size = 3
Post Call Size = -1
------------------
Thanks a lot Master CHI for have found this problem 8), because yesterday i have continue to reflect on my exemple, and not understand this crash :|

Code: Select all

Prototype AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")

Runtime Procedure MessageWithoutParameter()
 MessageRequester("Without Parameter", "No parameter")
EndProcedure

Runtime Procedure MessageOneParameter(Text.s)
 MessageRequester("Only one Parameter", Text)
EndProcedure

Runtime Procedure MessageTwoParameters(Text1.s, Text2.s)
 MessageRequester("Two parameters", Text1 + Text2)
EndProcedure

Runtime Procedure MessageThreeParameters(Text1.s, Text2.s, Text3.s)
 MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure

Procedure CallProcedure(NomProcedure.s, Parameter$ = "")
 
 *PtrProc = GetRuntimeInteger(NomProcedure + "()")
 Call.AllMessages = *PtrProc
 MaxParam = 0
 
 If Parameter$ <> ""
    
  MaxParam = CountString(Parameter$, ",") + 1
  Protected Dim ArrayParams.s(MaxParam)
 
  For i = 1 To MaxParam
   ArrayParams(i) = StringField(Parameter$, i, ",")
  Next
  
 EndIf
    
 Debug "Pre Call Size = " + ArraySize(ArrayParams())
 
 Select MaxParam
  Case 0
   Call()
  Case 1
   Call(ArrayParams(1))
   FreeArray(ArrayParams())
  Case 2
   Call(ArrayParams(1), ArrayParams(2))
   FreeArray(ArrayParams())
  Case 3 
   Call(ArrayParams(1), ArrayParams(2), ArrayParams(3))
   FreeArray(ArrayParams())
 EndSelect
 
 Debug "Post Call Size = " + ArraySize(ArrayParams())
 Debug "------------------"
  
EndProcedure

CallProcedure("MessageWithoutParameter")
CallProcedure("MessageOneParameter", "Hello it's KCC")
CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
The problem it's this time...is i'm not enough intelligent for explain that, to FRED :oops:

Surely he say to KCC, it's normal because he not use PB correctly, and when KCC not know the "PROTOTHINGS" it's better for him go to pick strawberries :mrgreen:
Never mind, i take the risk, and try to create a "Bug THREAD" about this subject for know the final word of this history, and know if it's or not my fault :wink:
viewtopic.php?p=530293#p530293

@ALL
Again thanks at all, for all your kind messages and precious helps

Kcc love you all !!!
Image
ImageThe happiness is a road...
Not a destination
breeze4me
Enthusiast
Enthusiast
Posts: 511
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Call procedure with several parameters by name

Post by breeze4me »

It crashes in x86 because of the difference between x86 calling convention and x64 calling convention, so you should use PrototypeC and ProcedureC.

Code: Select all

PrototypeC AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")

Runtime ProcedureC MessageOneParameter(Text.s)
  MessageRequester("Only one Parameter", Text)
EndProcedure

Runtime ProcedureC MessageTwoParameters(Text1.s, Text2.s)
  MessageRequester("Two parameters", Text1 + Text2)
EndProcedure

Runtime ProcedureC MessageThreeParameters(Text1.s, Text2.s, Text3.s)
  MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure

Procedure CallProcedure(NomProcedure.s, Parameter$)
  
  *PtrProc = GetRuntimeInteger(NomProcedure + "()")
  Call.AllMessages = *PtrProc
  MaxParam = CountString(Parameter$, ",") 
  Protected Dim ArrayParams.s(MaxParam)

  For i = 0 To MaxParam
    ArrayParams(i) = StringField(Parameter$, i+1, ",")
  Next
  
  Debug "Pre Call Size = " + ArraySize(ArrayParams()) 
  
  Select MaxParam
    Case 0
      Call(ArrayParams(0))
    Case 1
      Call(ArrayParams(0), ArrayParams(1))
    Case 2
      Call(ArrayParams(0), ArrayParams(1), ArrayParams(2))
  EndSelect
  
  FreeArray(ArrayParams())
  
  Debug "Post Call Size = " + ArraySize(ArrayParams()) 
  Debug "------------------"
  
EndProcedure

CallProcedure("MessageOneParameter", "Hello it's KCC")
CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Call procedure with several parameters by name

Post by Kwai chang caine »

Yeeeesss !!!!
You have totaly right, your code fix the bug !!! :shock:
Thanks to have found it 8)

Then, at your advice ..... is it a bad use of KCC, or an not normal behavior ?
ImageThe happiness is a road...
Not a destination
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Call procedure with several parameters by name

Post by chi »

breeze4me wrote:It crashes in x86 because of the difference between x86 calling convention and x64 calling convention, so you should use PrototypeC and ProcedureC.
Unfortunately [ Debug "Post Call Size = " + ArraySize(ArrayParams()) ] still returns -1 (also on x64 now)
Et cetera is my worst enemy
breeze4me
Enthusiast
Enthusiast
Posts: 511
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Call procedure with several parameters by name

Post by breeze4me »

Kwai chang caine wrote: Then, at your advice ..... is it a bad use of KCC, or an not normal behavior ?
a call stack corruption... it's not a good use. :wink:

chi wrote: Unfortunately [ Debug "Post Call Size = " + ArraySize(ArrayParams()) ] still returns -1 (also on x64 now)
ArrayParams() was freed, then the size is -1. It's normal.

Code: Select all

ArraySize()
......
Returns the size of the array dimension. If the array isn't yet declared (or its allocation has failed), it will return -1.

FreeArray()
......
Free the specified 'Array()' and release all its associated memory. To access it again Dim has to be called. 

Code: Select all

......
  FreeArray(ArrayParams())
  
  Debug "Post Call Size = " + ArraySize(ArrayParams()) 
  Debug "------------------"
......
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Call procedure with several parameters by name

Post by chi »

breeze4me wrote:ArrayParams() was freed, then the size is -1. It's normal.
Good point... You have changed the order (FreeArray() before ArraySize). I've missed that :oops:
Et cetera is my worst enemy
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Call procedure with several parameters by name

Post by Kwai chang caine »

breeze4me wrote:a call stack corruption... it's not a good use.
Aaaah ok ! :oops: Thanks MASTER for your explanation 8)
So, i want good understand, i must use your code with PrototypeC /ProcedureC or i don't use the prototype for this code :?:

@CHI
Again thanks CHI for your great help and your support in the other THREAD :wink: , it warmed my heart 8)
Before, you are for me one of my heroes, but this time i'm sure you are an hero, MASTER CHI rescue little KCC :lol:

Image
ImageThe happiness is a road...
Not a destination
breeze4me
Enthusiast
Enthusiast
Posts: 511
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Call procedure with several parameters by name

Post by breeze4me »

Kwai chang caine wrote:
breeze4me wrote:a call stack corruption... it's not a good use.
Aaaah ok ! :oops: Thanks MASTER for your explanation 8)
So, i want good understand, i must use your code with PrototypeC /ProcedureC or i don't use the prototype for this code :?:
Using PrototypeC /ProcedureC is a good way. But using Prototype/Procedure is no problem with some additional parts.
See the following code.

Code: Select all

Prototype AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")

Runtime Procedure MessageOneParameter(Text.s, Param2$ = "", Param3$ = "")
  MessageRequester("Only one Parameter", Text)
EndProcedure

Runtime Procedure MessageTwoParameters(Text1.s, Text2.s, Param3$ = "")
  MessageRequester("Two parameters", Text1 + Text2)
EndProcedure

Runtime Procedure MessageThreeParameters(Text1.s, Text2.s, Text3.s)
  MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure

Procedure CallProcedure(NomProcedure.s, Parameter$)
  
  *PtrProc = GetRuntimeInteger(NomProcedure + "()")
  Call.AllMessages = *PtrProc
  MaxParam = CountString(Parameter$, ",") 
  Protected Dim ArrayParams.s(MaxParam)

  For i = 0 To MaxParam
    ArrayParams(i) = StringField(Parameter$, i+1, ",")
  Next
  
  Debug "Pre Call Size = " + ArraySize(ArrayParams()) 
  
  Select MaxParam
    Case 0
      Call(ArrayParams(0))
    Case 1
      Call(ArrayParams(0), ArrayParams(1))
    Case 2
      Call(ArrayParams(0), ArrayParams(1), ArrayParams(2))
  EndSelect
  
  FreeArray(ArrayParams())
  
  Debug "Post Call Size = " + ArraySize(ArrayParams()) 
  Debug "------------------"
  
EndProcedure

CallProcedure("MessageOneParameter", "Hello it's KCC")
CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Call procedure with several parameters by name

Post by Kwai chang caine »

Aaaah!!! i have understand now what you try to explain kindly to me 8)

In fact my error is the prototype must have exactely the same number of parameters as the procedure called like this

Code: Select all

Prototype AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")

Runtime Procedure MessageOneParameter(Text.s, Param2$ = "", Param3$ = "")
  MessageRequester("Only one Parameter", Text)
EndProcedure
Then i can't use prototype, in this form, if i have this procedure like this

Code: Select all

Prototype AllMessages(Param1$ = "", Param2$ = "", Param3$ = "")

Runtime Procedure MessageOneParameter(Text.s)
  MessageRequester("Only one Parameter", Text)
EndProcedure
In fact,.....it's exactely what "Little John" explain to me, but with a little bit different method :mrgreen:
Image

and i must recognize, that does not have the same effect on me :oops:

Thanks a lot Breeze4Me for your precious help
Have a good day 8)
ImageThe happiness is a road...
Not a destination
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: [Resolved] Call procedure with several parameters by nam

Post by Kwai chang caine »

Thanks to several advices (Include Little John) i modify my code and apparently it works on X86 8)

Code: Select all

Prototype P0()
Prototype P1(Param1$ = "")
Prototype P2(Param1$ = "", Param2$ = "")
Prototype P3(Param1$ = "", Param2$ = "", Param3$ = "")
Prototype P4(Param1$ = "", Param2$ = "", Param3$ = "", Param4$ = "")
Prototype P5(Param1$ = "", Param2$ = "", Param3$ = "", Param4$ = "", Param5$ = "")

Runtime Procedure MessageWithoutParameter()
 MessageRequester("Without Parameter", "No parameter")
EndProcedure

Runtime Procedure MessageOneParameter(Text.s)
 MessageRequester("Only one Parameter", Text)
EndProcedure

Runtime Procedure MessageTwoParameters(Text1.s, Text2.s)
 MessageRequester("Two parameters", Text1 + Text2)
EndProcedure

Runtime Procedure MessageThreeParameters(Text1.s, Text2.s, Text3.s)
 MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure

Procedure CallProcedure(NomProcedure.s, Parameter$ = "")
 
 *PtrProc = GetRuntimeInteger(NomProcedure + "()")
 MaxParam = CountString(Parameter$, ",") + Bool(Parameter$ <> "")
 Protected Dim ArrayParams.s(MaxParam)
 
 If MaxParam
 
  For i = 1 To MaxParam
   ArrayParams(i) = StringField(Parameter$, i, ",")
  Next
  
 EndIf
 
 Debug "Pre Call Size = " + ArraySize(ArrayParams())
 
 Select MaxParam
  Case 0
   Call.P0 = *PtrProc
   Call()
  Case 1
   Call.P1 = *PtrProc
   Call(ArrayParams(1))
  Case 2
   Call.P2 = *PtrProc
   Call(ArrayParams(1), ArrayParams(2))
  Case 3
   Call.P3 = *PtrProc
   Call(ArrayParams(1), ArrayParams(2), ArrayParams(3))
  Case 4
   Call.P4 = *PtrProc
   Call(ArrayParams(1), ArrayParams(2), ArrayParams(3),ArrayParams(4))
  Case 5
   Call.P5 = *PtrProc
   Call(ArrayParams(1), ArrayParams(2), ArrayParams(3), ArrayParams(4), ArrayParams(5))
 EndSelect
 
 Debug "Post Call Size = " + ArraySize(ArrayParams())
 Debug "------------------"
 
 FreeArray(ArrayParams())
 
EndProcedure

CallProcedure("MessageWithoutParameter")
CallProcedure("MessageOneParameter", "Hello it's KCC")
CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
Thanks again at all 8)

PS:Fixed thanks to MESTNYI 8)
Last edited by Kwai chang caine on Sun Dec 16, 2018 6:09 pm, edited 1 time in total.
ImageThe happiness is a road...
Not a destination
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: [Resolved] Call procedure with several parameters by nam

Post by mestnyi »

Here are my two pennies.
So I think it will be faster more beautiful and clearer.

Code: Select all

MaxParam = CountString(Parameter$, ",")
 Protected Dim ArrayParams.s(MaxParam)
 MaxParam = 0
 
 If Parameter$ <> ""
   
  MaxParam = CountString(Parameter$, ",") + 1
  Protected Dim ArrayParams.s(MaxParam)
 
  For i = 1 To MaxParam
   ArrayParams(i) = StringField(Parameter$, i, ",")
  Next
 
 EndIf

Code: Select all

MaxParam = CountString(Parameter$, ",") + Bool(Parameter$ <> "")
  Protected Dim ArrayParams.s(MaxParam)
  
  If MaxParam
    For i = 1 To MaxParam
      ArrayParams(i) = StringField(Parameter$, i, ",")
    Next 
  EndIf
  
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: [Resolved] Call procedure with several parameters by nam

Post by Kwai chang caine »

Hello MESTNYI :D

Really interesting this part of your code :shock: we recognize the MASTER touch 8)

Code: Select all

+ Bool(Parameter$ <> "")
You have right, two time the same lines

Code: Select all

 MaxParam = CountString(Parameter$, ",") + 1
  Protected Dim ArrayParams.s(MaxParam)
and between erase "MaxParam' :shock:

By force, to all test, in every way....

Image

sometime it's better to go to bed :oops: or maybe again better...never leave it :mrgreen:
Thanks MASTER for your help 8)

To reach my primary goal, i search now if it's possible to write under this form (more professional 8) )

Code: Select all

CallProcedure("MessageTwoParameters", "Hello it's KCC a second time" ,  "but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time" , "and this time" , "it's one time too much")
instead of this, less nice :|

Code: Select all

CallProcedure("MessageTwoParameters", "Hello it's KCC a second time, but it's more long")
CallProcedure("MessageThreeParameters", "Hello it's KCC another time, and this time, it's one time too much")
But i believe, in PB it's impossible to count or know the numbers of parameters of a procedure :cry:

It's a pity "GetRuntimeString()" is not used for procedure :|
viewtopic.php?p=517231#p517231
That would be great if this function return the full procedure name "MessageThreeParameters(Text1.s, Text2.s, Text3.s)" if it's possible :idea:

Code: Select all

Runtime Procedure MessageThreeParameters(Text1.s, Text2.s, Text3.s)
 MessageRequester("Three parameters", Text1 + Text2 + Text3)
EndProcedure

Debug "Pointer of procedure = " + Trim(Str(GetRuntimeInteger("MessageThreeParameters" + "()")))
Debug "Full call of procedure = " + GetRuntimeString("MessageThreeParameters" + "()")
Compiler wrote:Pointer of procedure = 4198787
Full call of procedure = MessageThreeParameters(Text1.s, Text2.s, Text3.s)
Like this, i could count the numbers of parameters 8)

Again thanks for your interest
Have a good day
ImageThe happiness is a road...
Not a destination
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: [Resolved] Call procedure with several parameters by nam

Post by Mijikai »

This is a nice idea :)

I tried to make something that supports all parameter types.
However it fails and i dont know exactly why. :cry:
I thought it should not matter if the parameter is a int, float or double (in x64 asm all will be pushed as 8 bytes)...

Mby someone can tell my why i cant do this:

Code: Select all

;PB 5.62 x64

EnableExplicit

Global str.s
Global flt.f
Global par.i

Procedure.i ProcTest(TestString.s,TestParameter.f)
  MessageRequester("Test! ",TestString + " "  + StrF(TestParameter,3))
EndProcedure

str = "Hello World!"
flt = 123.456
par = PeekL(@flt)

Debug flt
PokeL(@flt,par)
Debug flt

ProcTest(str,flt)

CallFunctionFast(@ProcTest(),@str,flt);fails !?
CallFunctionFast(@ProcTest(),@str,par);fails !?

End
-> CallFunctionFast() always fails!!!
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: [Resolved] Call procedure with several parameters by nam

Post by Kwai chang caine »

Mijikai wrote:This is a nice idea
Thanks, it's an honor coming from you 8)
Obviously, i"m not enough strong for help you :oops:
I hope another MASTER can help
Mijikai wrote:-> CallFunctionFast() always fails!!!
Apparently not for me with W7 X86 / v5.62 x86

Here, only the first call

Code: Select all

CallFunctionFast(@ProcTest(),@str,flt)
return "0" in the second parameter "TestParameter" :wink:
The second

Code: Select all

CallFunctionFast(@ProcTest(),@str,par)
return "123.456"
ImageThe happiness is a road...
Not a destination
Post Reply