Welcome, Guest
Username: Password: Remember me
This public forum is meant for questions and discussions about Visual FoxPro
  • Page:
  • 1

TOPIC:

Variable number of parameters 18 May 2020 22:44 #14638

  • atlopes
  • atlopes's Avatar
  • Topic Author


  • Posts: 84
  • Sorry for what will likely be a very basic question, but in X# how can a function declaration specify an unknown, variable number of parameters?

    Something that could allow the implementation of the MIN() VFP function as close as possible to:
    MIN(eExpression1, eExpression2 [, eExpression3 ...])

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 18 May 2020 23:13 #14639

    • Chris
    • Chris's Avatar


  • Posts: 3980
  • António,

    There are two different ways. For untyped functions, you can use the PCount() / _GetFParam() pairs of intrinsic functions, to retrieve amount of parameters passed and each of them:

    FUNCTION UntypedFunc() CLIPPER
    FOR LOCAL n := 1 AS INT UPTO pcount()
    	? "Parameter" , n , "=" , _GetFParam(n)
    NEXT
    RETURN NIL


    For strongly typed functions/methods, you can use the same mechanism that c# uses as well, with the params keyword (ParamArray attribute in X#):

    FUNCTION TypedFunc([ParamArray] aParams AS OBJECT[]) AS VOID STRICT
    FOR LOCAL n := 1 AS INT UPTO aParams:Length
    	? "Parameter" , n , "=" , aParams[n]
    NEXT
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 19 May 2020 09:37 #14640

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hi Chris,

    When i compile your TypedFunc() i get the warning:

    warning XS0674: Do not use 'System.ParamArrayAttribute'. Use the 'params' keyword instead.

    Finally i found out how to use the PARAMS keyword:

        LOCAL c := "Wall" AS STRING 
    
    
        ?
        TypedFunc ( 1 , TRUE , , c )
        ?
        TypedFunc ()
    
    
    // FUNCTION TypedFunc([ParamArray] aParams AS OBJECT[]) AS VOID STRICT
    FUNCTION TypedFunc( aParams PARAMS OBJECT[] ) AS VOID STRICT   
    
    	? "Param count:" , aParams:Length
    		
    	FOREACH VAR a IN aParams   
    		? ValType ( a ) , a , IsNil ( a )    // ok 
    		
    	NEXT 
    	
    	RETURN  
     

    Isn´t it possible to pass a var by ref ? I tried "@c" and "REF c" but that doesn´t work.

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 19 May 2020 09:48 #14641

    • Chris
    • Chris's Avatar


  • Posts: 3980
  • Hi Karl-Heinz,

    Ah, right I keep forgetting that it is possible to also use the PARAMS keyword!

    No, you can't pass params by reference like that, after all there's not a parameter variable name in the receiving function to assign back a new value to it. You could say you could put back the value to the array element, but if you want to do this, you can pass an array to a regular function in the first place...
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 19 May 2020 09:55 #14642

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Chris wrote: Hi Karl-Heinz,

    No, you can't pass params by reference like that...


    thanks, already thought that this would not work.

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 19 May 2020 13:41 #14645

    • atlopes
    • atlopes's Avatar
    • Topic Author


  • Posts: 84
  • Thank you both, Chris and Karl-Heinz. I'm experimenting with this and it is working.

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 20 May 2020 13:54 #14648

    • leon-ts
    • leon-ts's Avatar


  • Posts: 277
  • Hi to all!

    Is there any way to save information about parameter types when calling functions with a variable number of parameters?

    For example, there is a function:
    FUNCTION MyTestFunc(a PARAMS OBJECT[]) AS VOID
    	
    	? a[1]:GetType():FullName
    	? a[2]:GetType():FullName
    	? a[3]:GetType():FullName
    	? a[4]:GetType():FullName
    	
    	RETURN

    All options in the project properties in the "Language" and "Dialect" sections (except for Unsafe code) are disabled (FALSE).

    Call:
    MyTestFunc( NULL_PTR, "abc", (DWORD)1, NULL_STRING )

    Result:

    a[1]: System.IntPtr, OBJECT {PTR}
    a[2]: System.String, OBJECT {STRING}
    a[3]: System.UInt32, OBJECT {DWORD}
    a[4]: null, OBJECT // exception


    Type information lost for a[4]

    Enable the "Allow late binding" property in TRUE.
    Call function (previous example)

    Result:

    a[1]: null, OBJECT // exception
    a[2]: System.String, OBJECT {STRING}
    a[3]: System.UInt32, OBJECT {DWORD}
    a[4]: null, OBJECT // exception


    Type information lost for a[1] and a[4]

    Best regards,
    Leonid
    Best regards,
    Leonid

    Please Log in or Create an account to join the conversation.

    Last edit: by leon-ts.

    Variable number of parameters 20 May 2020 16:42 #14650

    • robert
    • robert's Avatar


  • Posts: 3595
  • Leonid,

    The /vo2 compiler setting determines how NULL_STRING is interpreted.
    With /vo2+ it will replace NULL_STRING with String.Empty. In that case the 4th parameter will have the right type.
    When I run your code with only /vo2+ I see the following result
    System.IntPtr
    System.String
    System.UInt32
    System.String

    I fyou look at the code with ILSpy you will see that the NULL_PTR is translated to
    IntPtr.Zero
    When I enable /lb+ I see that the translation of NULL_PTR has become
    (long)IntPtr.Zero

    I am not sure why that is, but this needs to be fixed.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 20 May 2020 20:10 #14651

    • leon-ts
    • leon-ts's Avatar


  • Posts: 277
  • Robert,

    I turned on /vo2+ and I managed to save the string type. This is what I need. But PTR is still a problem. It comes into function as NULL.

    I modified the example a bit as follows.
    FUNCTION MyTestFunc(p AS PTR, a PARAMS OBJECT[]) AS VOID
    	RETURN
    And Call:
    MyTestFunc( NULL_PTR, NULL_PTR, "abc", (DWORD)1, NULL_STRING )
    The parameter 'p' takes the type System.Void *. And this is exactly the type that I expect. In particular, I expect this from type a[1], because NULL_PTR is also passed to it, but this does not happen. It contains NULL. (at /lb+ and at /lb-)

    When I create a library (.dll) in XSharp and place a function in it, where one or several parameters are described as AS PTR, then if you look at its MethodInfo, it shows this parameter as type System.Void * (not System.IntPtr). If the function has overloads, then in order to correctly extract the necessary overload using the Type.GetMethod() method, I need to pass in it an array of exact parameter types of the desired function. And if you pass System.IntPtr to the example I gave, instead of System.Void *, then Type.GetMethod() will return null (not found).

    P.S. I am developing a generic function to call other functions from dynamically loaded assemblies. AssemblyName, ClassName, FunctionName and parameters of the called function (variable length, via PARAMS) are passed to this general function. And for this it is very important to extract valid types from PARAMS.

    P.S.2. The problematic example is in the attachment.

    Best regards,
    Leonid
    Best regards,
    Leonid

    Please Log in or Create an account to join the conversation.

    Last edit: by leon-ts.

    Variable number of parameters 21 May 2020 10:39 #14658

    • robert
    • robert's Avatar


  • Posts: 3595
  • Leonid,

    I already confirmed that there is a problem with NULL_PTR being passed incorrectly to a function that takes a PARAMS OBJECT[] yesterday when /lb+ is enabled.
    I am already working on this.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 21 May 2020 10:54 #14660

    • leon-ts
    • leon-ts's Avatar


  • Posts: 277
  • Robert,

    robert wrote: I already confirmed that there is a problem with NULL_PTR

    Yes, thanks!
    I just made an additional clarification about the type System.Void*, because your post was about System.IntPtr.

    Best regards,
    Leonid
    Best regards,
    Leonid

    Please Log in or Create an account to join the conversation.

    Last edit: by leon-ts.

    Variable number of parameters 21 May 2020 11:07 #14661

    • leon-ts
    • leon-ts's Avatar


  • Posts: 277
  • I just discovered one more problem. I don’t know if it is related to the previous problem (NULL_PTR), so I will describe it here. If you pass a non-NULL PTR parameter to the function, a FatalExecutionEngineError exception is thrown.

    Example (function):
    FUNCTION MyTestFunc(a PARAMS OBJECT[]) AS VOID
    	RETURN
    Call:
    VAR p := (PTR)0x0234FF01
    MyTestFunc( p, "abc", (DWORD)1, NULL_STRING )

    Best regards,
    Leonid
    Best regards,
    Leonid

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 21 May 2020 15:33 #14665

    • robert
    • robert's Avatar


  • Posts: 3595
  • Leonid,

    The Ptr problems are now solved. When a Intptr, void* or any pointer at all is assigned to an object it is now "boxed". And when it assigned back it is "unboxed".

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Variable number of parameters 21 May 2020 15:37 #14666

    • leon-ts
    • leon-ts's Avatar


  • Posts: 277
  • Robert,

    This is very good news! Thanks!

    Best regards,
    Leonid
    Best regards,
    Leonid

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1