Seite 1 von 1

Proceduren mit einer variablen Anzahl an Parametern

Verfasst: 16.03.2012 19:15
von ts-soft
Ich glaube, wir hatten hier schon ähnliche Beiträge, konnte die aber nicht finden.

Aus C, Freebasic oder anderen Sprachen kennt Ihr vielleicht Funktionsaufrufe, mit
variabler Parameteranzahl, meist durch 3 Punkte dargestellt.

Ich hab hier mal eine Variante für PB gebastelt, die vielleicht für den einen oder
anderen nützlich sein könnte.

ACHTUNG: Für strings bitte unbedingt das Beispiel angucken!

Die Übergabe erfolgt per strukturiertem Array. Das weitere kann man aus dem
Code ersehen.
Parameter werden mit der Procedure V_ARG_Add() hinzugefügt.
Wenn alle Parameter hinzugefügt wurden, dann unser Procedure,
siehe Foo(), mit diesem Array aufrufen.

Code: Alles auswählen

;==================================================================
; ###  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())


Re: Proceduren mit einer variablen Anzahl an Parametern

Verfasst: 16.03.2012 19:38
von STARGÅTE
Hier ist der Beitrag (von mir) den du vermutlich gesucht hast:
DimP - Viele ProcedurParameter (max 16) als Array verwenden

Deine Lösung nimmt einem ja nicht wirklich viel Arbeit ab ^^

Re: Proceduren mit einer variablen Anzahl an Parametern

Verfasst: 16.03.2012 19:45
von ts-soft
STARGÅTE hat geschrieben:Hier ist der Beitrag (von mir) den du vermutlich gesucht hast:
DimP - Viele ProcedurParameter (max 16) als Array verwenden

Deine Lösung nimmt einem ja nicht wirklich viel Arbeit ab ^^
Meine Lösung ist aber nicht auf einen typ und 16 Parameter begrenzt :wink:

Es soll auch nicht unbedingt eine Arbeitserleichterung sein, sondern eher ein Beispiel,
wie man so etwas umsetzen könnte.

// edit
hier mal ein Beispiel, wie so etwas in FB aussieht:

Code: Alles auswählen

Sub myPrint Cdecl (FormatierString As String, ...)
  Dim As Any Ptr argument = va_first()
  Dim As Integer i
  Dim As ZString Ptr p
  
  For i = 1 To Len(FormatierString)
  
    Select Case Mid(FormatierString, i, 1)
      Case "i"
        Print "Integer: " & va_arg(argument, Integer)
        argument = va_next(argument, Integer)
      Case "l"
        Print "LongInt: " & va_arg(argument, LongInt)
        argument = va_next(argument, LongInt)
      Case "f", "d"
        Print "Double: " & va_arg(argument, Double)
        argument = va_next(argument, Double)
      Case "s"
        Print "String: " & *va_arg(argument, ZString Ptr)
        argument = va_next(argument, ZString Ptr)
    End Select
  Next
End Sub

'###############################################################

Dim s As String = "String2"

myPrint( "ilfdss", 1, 4294967296, 1.2, 3.4, "String1", s )
Sleep

Re: Proceduren mit einer variablen Anzahl an Parametern

Verfasst: 16.03.2012 19:58
von STARGÅTE
Jo, klar, aber du übergibst ja nicht wirklich mehrer Parameter, sonden trotzdem nur einen.
In meinem Code war es ja damals wirklich so, dass echte Parameter übergeben wurde, und da brauchst man in der regel nicht mehr als 16.
Wenn man 100 Parameter übergeben will, ist das sowieso der falsche Weg ...

Mir ging es damals wirklich nur um Max/Min-Sachen, wo man mal 2 bis 5 Elemente hat.

Bei dir ist natürlich der Vorteil, dass du viele verschiede Typen Parameter übergeben kannst :allright:

Re: Proceduren mit einer variablen Anzahl an Parametern

Verfasst: 19.03.2012 13:09
von mk-soft
@ts-soft

Ist schon sehr lange her was du suchtest.

http://www.purebasic.fr/german/viewtopi ... 08&start=0

P.S. Bügelt aber immer 12 Parameter auf den Stack. Vielleicht das macro Args nach bedarf einschränken...

P.S. Bei Variablentype die vorher nicht definiert sind nehme ich immer Variant...