Page 1 of 1
Simple way to use variable parameters for Procedures
Posted: Fri Mar 16, 2012 6:26 pm
by ts-soft
Code: Select all
;==================================================================
; ### Example to use variable parameters for Procedures ###
; Author: Thomas <ts-soft> Schulz
; Date: Mrz 16, 2012
; Version: 1.0
; Target OS: All
; Target Compiler: PureBasic 4.40 and later
;==================================================================
EnableExplicit
Structure V_ARG
Type.l
StructureUnion
a.a
b.b
c.c
d.d
f.f
i.i
l.l
*s.String
q.q
u.u
w.w
EndStructureUnion
EndStructure
Procedure V_ARG_Add(Array V_ARG.V_ARG(1), Type.l, *value)
Protected index = ArraySize(V_ARG())
Protected *v.Quad = *value
ReDim V_ARG(index + 1)
With V_ARG(index)
\Type = Type
\q = *v\q
EndWith
EndProcedure
; example
Procedure Foo(Array V_ARG.V_ARG(1))
Protected i
Protected count = ArraySize(V_ARG())
Debug "Count of parameters: " + Str(count)
Debug ""
For i = 0 To count - 1
With V_ARG(i)
Select \Type
Case #PB_Ascii
Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
Case #PB_Byte
Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
Case #PB_Character
Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
Case #PB_Double
Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
Case #PB_Float
Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
Case #PB_Integer
Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
Case #PB_Long
Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
Case #PB_Quad
Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
Case #PB_String
Debug "Parameter " + Str(i + 1) + " = String, Value = " + PeekS(V_ARG(i)\s)
Case #PB_Unicode
Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
Case #PB_Word
Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
EndSelect
EndWith
Next
EndProcedure
Dim para_array.V_ARG(0)
Define Text.String
Text\s = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), #PB_String, @Text)
Define pi.d = #PI
V_ARG_Add(para_array(), #PB_Double, @pi)
Define word.w = 65535
V_ARG_Add(para_array(), #PB_Word, @word)
V_ARG_Add(para_array(), #PB_Unicode, @word)
Foo(para_array())
Have Fun

Re: Simple way to use variable parameters for Procedures
Posted: Sat Mar 17, 2012 2:44 am
by IdeasVacuum
woa, that's too clever.........

Re: Simple way to use variable parameters for Procedures
Posted: Sat Mar 17, 2012 5:57 pm
by rsts
IdeasVacuum wrote:woa, that's too clever.........

Mr Soft is VERY clever
Thanks for sharing.
Re: Simple way to use variable parameters for Procedures
Posted: Sat Mar 17, 2012 6:03 pm
by ts-soft
You can use this, for example a interpreter like program, using only one prototype for all functions.
It is simple, as the title say, but it is a hint for some projects.
Re: Simple way to use variable parameters for Procedures
Posted: Sun Jan 12, 2014 8:02 pm
by NicTheQuick
This version makes it a little bit easier to use. The type and size of a variable will be set automatically (since PB V5.1). But be careful if the variable has the same name as a structure. In this case there will be pop out a compiler error.
Code: Select all
;==================================================================
; ### Example to use variable parameters for Procedures ###
; Author: Thomas <ts-soft> Schulz & <NicTheQuick>
; Date: Mrz 16, 2012
; Version: 1.1
; Target OS: All
; Target Compiler: PureBasic 5.10 and later
;==================================================================
EnableExplicit
Structure V_ARG
Type.l
StructureUnion
a.a
b.b
c.c
d.d
f.f
i.i
l.l
q.q
u.u
w.w
EndStructureUnion
s.s
EndStructure
Procedure V_ARG_Add_(Array V_ARG.V_ARG(1), Type.l, size.i, *value)
Protected index = ArraySize(V_ARG())
ReDim V_ARG(index + 1)
With V_ARG(index)
\Type = Type
If (Type = #PB_String)
\s = PeekS(*value)
Else
CopyMemory(*value, @V_ARG(index) + OffsetOf(V_ARG\a), size)
EndIf
EndWith
EndProcedure
Macro V_ARG_Add(v_arg, value)
CompilerIf TypeOf(value) = #PB_Structure
CompilerError "The variable has no native type. This is not supported."
CompilerEndIf
V_ARG_Add_(v_arg, TypeOf(value), SizeOf(value), @value)
EndMacro
; example
Procedure Foo(Array V_ARG.V_ARG(1))
Protected i.i
Protected count.i = ArraySize(V_ARG())
Debug "Count of parameters: " + Str(count)
Debug ""
For i = 0 To count - 1
With V_ARG(i)
Debug \Type
Select \Type
Case #PB_Ascii
Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
Case #PB_Byte
Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
Case #PB_Character
Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
Case #PB_Double
Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
Case #PB_Float
Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
Case #PB_Integer
Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
Case #PB_Long
Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
Case #PB_Quad
Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
Case #PB_String
Debug "Parameter " + Str(i + 1) + " = String, Value = " + V_ARG(i)\s
Case #PB_Unicode
Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
Case #PB_Word
Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
EndSelect
EndWith
Next
EndProcedure
Dim para_array.V_ARG(0)
Define Text.s
Text = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), Text)
Define pi.d = #PI
V_ARG_Add(para_array(), pi)
Define word1.w = 65535
V_ARG_Add(para_array(), word1)
V_ARG_Add(para_array(), word1)
Foo(para_array())
Re: Simple way to use variable parameters for Procedures
Posted: Mon Jan 13, 2014 12:13 pm
by Kwai chang caine
Very usefull code, thanks a lot for sharing

Re: Simple way to use variable parameters for Procedures
Posted: Thu Sep 03, 2015 7:35 pm
by GPI
My Variant

Call supports here up to 10 parameters.
Code: Select all
;==================================================================
; ### Example to use variable parameters for Procedures ###
; Author: Thomas <ts-soft> Schulz & <NicTheQuick>
; Date: Mrz 16, 2012
; Version: 1.1
; Target OS: All
; Target Compiler: PureBasic 5.10 and later
;==================================================================
EnableExplicit
Macro MacroQuote
"
EndMacro
Structure V_ARG
Type.l
StructureUnion
a.a
b.b
c.c
d.d
f.f
i.i
l.l
q.q
u.u
w.w
EndStructureUnion
s.s
EndStructure
Procedure V_ARG_Add_(Array V_ARG.V_ARG(1), Type.l, size.i, *value)
Protected index = ArraySize(V_ARG())
ReDim V_ARG(index + 1)
With V_ARG(index)
\Type = Type
If (Type = #PB_String)
\s = PeekS(*value)
Else
CopyMemory(*value, @V_ARG(index) + OffsetOf(V_ARG\a), size)
EndIf
EndWith
EndProcedure
Macro V_ARG_START
Dim __varg.V_ARG(0)
EndMacro
Macro V_ARG_Add(value)
CompilerIf TypeOf(value) = #PB_Structure
CompilerError "The variable has no native type. This is not supported."
CompilerEndIf
V_ARG_Add_(__varg(), TypeOf(value), SizeOf(value), @value)
EndMacro
Macro V_ARG_LIST
__varg()
EndMacro
Macro V_ARG_END
FreeArray(__varg())
EndMacro
Macro Call(ret,proc,a1=,a2=,a3=,a4=,a5=,a6=,a7=,a8=,a9=,a10=)
V_ARG_START
CompilerIf MacroQuote#a1#Macroquote<>""
V_ARG_Add(a1)
CompilerEndIf
CompilerIf MacroQuote#a2#Macroquote<>""
V_ARG_Add(a2)
CompilerEndIf
CompilerIf MacroQuote#a3#Macroquote<>""
V_ARG_Add(a3)
CompilerEndIf
CompilerIf MacroQuote#a4#Macroquote<>""
V_ARG_Add(a4)
CompilerEndIf
CompilerIf MacroQuote#a5#Macroquote<>""
V_ARG_Add(a5)
CompilerEndIf
CompilerIf MacroQuote#a6#Macroquote<>""
V_ARG_Add(a6)
CompilerEndIf
CompilerIf MacroQuote#a7#Macroquote<>""
V_ARG_Add(a7)
CompilerEndIf
CompilerIf MacroQuote#a8#Macroquote<>""
V_ARG_Add(a8)
CompilerEndIf
CompilerIf MacroQuote#a9#Macroquote<>""
V_ARG_Add(a9)
CompilerEndIf
CompilerIf MacroQuote#a10#Macroquote<>""
V_ARG_Add(a10)
CompilerEndIf
CompilerIf MacroQuote#ret#MacroQuote="#Null"
proc ( V_ARG_LIST )
CompilerElse
ret = proc ( V_ARG_LIST )
CompilerEndIf
V_ARG_END
EndMacro
; example
Procedure Foo(Array V_ARG.V_ARG(1))
Protected i.i
Protected count.i = ArraySize(V_ARG())
Debug "Count of parameters: " + Str(count)
Debug ""
For i = 0 To count - 1
With V_ARG(i)
Debug \Type
Select \Type
Case #PB_Ascii
Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
Case #PB_Byte
Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
Case #PB_Character
Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
Case #PB_Double
Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
Case #PB_Float
Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
Case #PB_Integer
Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
Case #PB_Long
Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
Case #PB_Quad
Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
Case #PB_String
Debug "Parameter " + Str(i + 1) + " = String, Value = " + V_ARG(i)\s
Case #PB_Unicode
Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
Case #PB_Word
Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
EndSelect
EndWith
Next
ProcedureReturn count
EndProcedure
V_ARG_START
Define Text.s
Text = "Feel the ..Pure.. Power"
V_ARG_Add( Text)
Define pi.d = #PI
V_ARG_Add( pi)
Define word1.w = 65535
V_ARG_Add(word1)
V_ARG_Add( word1)
Foo(V_ARG_LIST)
V_ARG_END
Call(#Null,Foo,text,pi,word1,pi,word1)
Call(#Null,Foo,text,pi,pi,pi,pi)
Define ret.i
call(ret,Foo,pi,text)
Debug "Return:"+Str(ret)
Re: Simple way to use variable parameters for Procedures
Posted: Tue Nov 03, 2015 6:00 pm
by NicTheQuick
Make it a "Threaded Dim" and you also have thread support.
