Seite 2 von 2

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 10:23
von Mijikai
NicTheQuick hat geschrieben:Leider funktioniert diese schwarze Magie nicht unter Linux.
Es sollte nicht allzu schwierig sein den Code für Linux anzupassen.

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 10:24
von Josh
NicTheQuick hat geschrieben:Leider funktioniert diese schwarze Magie nicht unter Linux.
Und auch nicht unter Win7 x64 mit Pb x32

Trotzdem interessant, was man mit Magie alles machen kann :D

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 10:40
von DrShrek
Kiffi hat geschrieben: Prinzipiell möchte ich via TCP/IP Runtime-Prozeduren in meinem Programm aufrufen. Diese haben generell eine feste Anzahl von Übergabeparametern.

Wenn ich allerdings im Eifer des Gefechts bei einer neuen Runtime-Prozedur den Parameter vergesse, schmiert mein Programm ab. Das finde ich unschick. Wäre schöner, wenn man das vorher testen könnte.
Schade & Danke Euch beiden & Grüße ... Peter
@Kiffi
Also "irgendeine" Procedure aufrufen macht doch nicht wirklich Sinn, oder?
Im Normalfall KENNT der Benutzer/Entwickler die Funktionen die er aufrufen möchte und auch welche Parameter diese haben möchten.

Header und Prototyping sagen den Compiler ob alles gesetzt wurde...ansonsten gibt es Errors oder zumindestens Warnings

Also

Code: Alles auswählen

EnableExplicit
Declare Funk(par1, par2)
sollten ausreichend sein.

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 10:43
von Mijikai
Josh hat geschrieben:
NicTheQuick hat geschrieben:Leider funktioniert diese schwarze Magie nicht unter Linux.
Und auch nicht unter Win7 x32
Alle Informationen bezüglich der Anwendbarkeit stehen in meinem Beitrag.
Für x86 muss der Code natürlich erst angepasst werden da x64 eine andere Aufrufkonvention hat.

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 11:01
von DrShrek
Mijikai hat geschrieben:Wenn es eine PureBasic Funktion ist geht es mit etwas schwarzer Magie ;)
Alles schön und gut...aber wer benutzt Funktion (egal woher oder welche Sprache) ohne zu wissen, welche Parameter diese benötigt und was die Funktion tut?

Eine möglicher Grund wäre Polymorphie, aber sorry: PB unterstützt das nicht wirklich

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 11:12
von mk-soft
DrShrek hat geschrieben: Eine möglicher Grund wäre Polymorphie, aber sorry: PB unterstützt das nicht wirklich
Das vermisste ich auch...

Habe mal den VarType Any mal in ein Module gepackt

Code: Alles auswählen


;-TOP

; Runtime Procedure mit festen Parametern

EnableExplicit

; *************************************************************************************************

DeclareModule Any
  
  Structure udtAny
    Type.i
    StructureUnion
      lVal.l
      iVal.i
      qVal.q
      fltVal.f
      dblVal.d
    EndStructureUnion
    strVal.s
  EndStructure
  
  Macro SetAny(Var, Value)
    Var\Type = TypeOf(Value)    
    CompilerSelect TypeOf(Value)
      CompilerCase #PB_Long
        Var\lVal = Value : Var\strVal = #Null$
      CompilerCase #PB_Integer
        Var\iVal = Value : Var\strVal = #Null$
      CompilerCase #PB_Quad
        Var\qVal = Value : Var\strVal = #Null$
      CompilerCase #PB_Float
        Var\fltVal = Value : Var\strVal = #Null$
      CompilerCase #PB_Double
        Var\dblVal = Value : Var\strVal = #Null$
      CompilerCase #PB_String
        Var\strVal = Value
    CompilerEndSelect
  EndMacro
  
  Macro FreeAny(Var)
    FreeStructure(Var)
  EndMacro
  
  Declare AnyL(Value.l)
  Declare AnyI(Value.i)
  Declare AnyQ(Value.q)
  Declare AnyF(Value.f)
  Declare AnyD(Value.d)
  Declare AnyS(Value.s)
  
EndDeclareModule

Module Any
  
  Procedure AnyL(Value.l)
    Protected *Any.udtAny = AllocateStructure(udtAny)
    If *Any
      *Any\Type = #PB_Long
      *Any\lVal = Value
    EndIf
    ProcedureReturn *Any
  EndProcedure
  
  Procedure AnyI(Value.i)
    Protected *Any.udtAny = AllocateStructure(udtAny)
    If *Any
      *Any\Type = #PB_Integer
      *Any\iVal = Value
    EndIf
    ProcedureReturn *Any
  EndProcedure
  
  Procedure AnyQ(Value.q)
    Protected *Any.udtAny = AllocateStructure(udtAny)
    If *Any
      *Any\Type = #PB_Quad
      *Any\qVal = Value
    EndIf
    ProcedureReturn *Any
  EndProcedure
  
  Procedure AnyF(Value.f)
    Protected *Any.udtAny = AllocateStructure(udtAny)
    If *Any
      *Any\Type = #PB_Float
      *Any\fltVal = Value
    EndIf
    ProcedureReturn *Any
  EndProcedure
  
  Procedure AnyD(Value.d)
    Protected *Any.udtAny = AllocateStructure(udtAny)
    If *Any
      *Any\Type = #PB_Double
      *Any\dblVal = Value
    EndIf
    ProcedureReturn *Any
  EndProcedure
  
  Procedure AnyS(Value.s)
    Protected *Any.udtAny = AllocateStructure(udtAny)
    If *Any
      *Any\Type = #PB_String
      *Any\strVal = Value
    EndIf
    ProcedureReturn *Any
  EndProcedure
  
EndModule

; *************************************************************************************************

;-Test

UseModule Any

Macro RT_AnyArgs
  *Arg1.udtAny=0, *Arg2.udtAny=0, *Arg3.udtAny=0, *Arg4.udtAny=0, *Arg5.udtAny=0, *Arg6.udtAny=0, *Arg7.udtAny=0, *Arg8.udtAny=0
EndMacro

Prototype RT_Invoke(RT_AnyArgs)

; IDE Helper
Define *Arg1.udtAny, *Arg2.udtAny, *Arg3.udtAny, *Arg4.udtAny, *Arg5.udtAny, *Arg6.udtAny, *Arg7.udtAny, *Arg8.udtAny


Runtime Procedure myProc1(RT_AnyArgs)
  Debug "*** Proc 1 ***"
  If *Arg1 And *Arg1\Type = #PB_String
    Debug "Text = " + *Arg1\strVal
    FreeAny(*arg1)
  Else
    Debug "Error: p1 falscher Type"
  EndIf
EndProcedure

Runtime Procedure myProc2(RT_AnyArgs)
  Debug "*** Proc 2 ***"
  Debug *Arg1\strVal + *Arg2\dblVal
  FreeAny(*Arg1)
  FreeAny(*Arg2)
EndProcedure

Runtime Procedure myProc3(RT_AnyArgs)
  Debug "*** Proc 3 ***"
  Debug "Arg 8 = " + *Arg8 
EndProcedure


Define.udtAny *p1 = AnyI(0)

Define ProcedureName.s = "myProc1()"

Define s1.s = "Hello World"
SetAny(*p1.udtAny, s1)

If IsRuntime(ProcedureName)
  Define ProcedureAddress.RT_Invoke = GetRuntimeInteger(ProcedureName)
  If ProcedureAddress
    ProcedureAddress(*p1) ; OK
  EndIf
EndIf

Define ProcedureName.s = "myProc2()"

If IsRuntime(ProcedureName)
  Define ProcedureAddress.RT_Invoke = GetRuntimeInteger(ProcedureName)
  If ProcedureAddress
    ProcedureAddress(AnyS("Result = "), AnyD(12345.12345)) ; OK
  EndIf
EndIf

ProcedureName.s = "myProc3()"
If IsRuntime(ProcedureName)
  ProcedureAddress.RT_Invoke = GetRuntimeInteger(ProcedureName)
  If ProcedureAddress
    ProcedureAddress(1, 2, 3, 4, 5, 6, 7, 8) ; OK
  EndIf
EndIf

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 03.08.2018 12:59
von #NULL
Das hat mit Polymorphie direkt nichts zu tun, es geht hier rein um Introspection allgemein. Da es die in der Art nicht gibt, muss man eben entweder eine Liste aus funktionen/prototypen manuell verwalten, oder den code selbst parsen (oder eben mit Magie).
Alles schön und gut...aber wer benutzt Funktion (egal woher oder welche Sprache) ohne zu wissen, welche Parameter diese benötigt und was die Funktion tut?
Ein webservice der abstürzt weil er unguten Input erhält ist nunmal doof, deshalb will Kiffi eben prüfen ob der Input auch auf eine Prozedur passt und er will das nicht für jede Funktion manuell testen.

Re: Ermitteln, ob Runtime-Procedure Parameter entgegennimmt

Verfasst: 15.08.2018 10:40
von RSBasic
@Mijikai
Cooler Code, danke. :allright: