• OCX (ActiveX) returning of multiple floats

    From R.Wieser@21:1/5 to All on Wed Aug 16 13:22:54 2023
    Hello all,

    I've got an OCX/ActiveX object which has a method which is, in the IDL file, described as follows :

    HRESULT SetData([in] float val1,[in] float val2,[in] float val3);

    I just tried to write a method to retrieve that data again, and its descriptione looks like this :

    HRESULT GetData([in] float* val1,[in] float* val2,[in] float* val3);

    When I try to call the methods from within VBScript like this :

    call oData.SetData(1,2,3)

    call oData.GetData(v1,v2,v3)
    -or-
    oData.GetData v1,v2,v3

    the "SetData" one works, but for some reason the "GetData" ones (both)
    generate an "type mismatch" error (and the methods code in the OCX doesn't
    get called).

    My question : what should the "GetData" description in the IDL look like ?


    Remark :
    I got the "GetData" method to work by changing the "float*" to "variant*"
    (and change the called method accordingly), but would like to have both
    methods and arguments to be copies of each other - just working in opposite directions.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul N@21:1/5 to R.Wieser on Wed Aug 16 06:55:59 2023
    On Wednesday, August 16, 2023 at 12:23:20 PM UTC+1, R.Wieser wrote:
    Hello all,

    I've got an OCX/ActiveX object which has a method which is, in the IDL file, described as follows :

    HRESULT SetData([in] float val1,[in] float val2,[in] float val3);

    I just tried to write a method to retrieve that data again, and its descriptione looks like this :

    HRESULT GetData([in] float* val1,[in] float* val2,[in] float* val3);

    When I try to call the methods from within VBScript like this :

    call oData.SetData(1,2,3)

    call oData.GetData(v1,v2,v3)
    -or-
    oData.GetData v1,v2,v3

    the "SetData" one works, but for some reason the "GetData" ones (both) generate an "type mismatch" error (and the methods code in the OCX doesn't get called).

    My question : what should the "GetData" description in the IDL look like ?

    I don't know VBScript at all, so I can't give you the full answer, but the problem seems to be that in SetData you simply pass in the values you want to use, whereas with GetData you pass in pointers - that is to say, you are telling it where to put the
    answers. In C, oData.GetData(v1,v2,v3) would try to pass in the values of v1 etc, and you would need to change it to oData.GetData(&v1,&v2,&v3) to tell it to pass in addresses. Presumably VBScript has something similar. You'll need to check what it is
    and use it.

    Remark :
    I got the "GetData" method to work by changing the "float*" to "variant*" (and change the called method accordingly), but would like to have both methods and arguments to be copies of each other - just working in opposite directions.

    The raw SetData and GetData functions are not quite quite "copies of each other" as one takes pointers and the other doesn't, but presumably you could write a "wrapper" function around them if you wanted to to make them similar. For instance in C++:

    void mySetData(something &o, float* val1, float* val2, float* val3) { o.SetData(*val1, *val2, *val3); } // asterisks to read the values at the pointers

    void myGetData(something &o, float* val1, float* val2, float* val3) { o.GetData(val1, val2, val3); } // here we want to just pass on the pointers

    Hope that is useful!
    Paul.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Wed Aug 16 22:15:05 2023
    On Wed, 16 Aug 2023 13:22:54 +0200, R.Wieser wrote:

    HRESULT GetData([in] float* val1,[in] float* val2,[in] float* val3);

    That should be defined as:

    HRESULT GetData([in, out] float* val1,[in, out] float* val2,[in, out] float* val3);

    Otherwise, the function will get the pointer to the copy of the given
    values. Because VBScript can not specifically pass a function argument by reference. e.g. this will cause a syntax error:

    retVal = obj.GetData(byref v1, byref v2, byref v3)

    In VBScript, the use of `byref` operator outside of a subroutine/function declaration, is not available. It's only available in VB/VBA.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to All on Wed Aug 16 22:18:46 2023
    On Wed, 16 Aug 2023 22:15:05 +0700, JJ wrote:
    On Wed, 16 Aug 2023 13:22:54 +0200, R.Wieser wrote:

    HRESULT GetData([in] float* val1,[in] float* val2,[in] float* val3);

    That should be defined as:

    HRESULT GetData([in, out] float* val1,[in, out] float* val2,[in, out] float* val3);

    Otherwise, the function will get the pointer to the copy of the given
    values. Because VBScript can not specifically pass a function argument by reference. e.g. this will cause a syntax error:

    retVal = obj.GetData(byref v1, byref v2, byref v3)

    In VBScript, the use of `byref` operator outside of a subroutine/function declaration, is not available. It's only available in VB/VBA.

    IDL example for a method which uses its multiple arguments as output is the IWebBrowserApp::ClientToWindow, which is defined in SHDOCVW.DLL's type
    library.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Wed Aug 16 17:24:01 2023
    Paul,

    I don't know VBScript at all,

    Thats a bit of a problem.

    You see, in VBScript /all/ variables are variants, converted to whatever is needed by the OCX objects methods by a translation layer. When my SetData code requires three floats the in the VBScript code provided variant
    arguments are taken by the translation layer and from whetever data is in
    them (floats, ints, strings, bools, etc, null, empty) a float is extracted (silent conversion) and passed on.

    IOW, all data in VBScript is, AFAIK, provided to the translation layer "by
    ref" (wrapped in a variant).

    ... and that is why I don't quite get why it works one way, but not the
    other ...

    In C .... you would need to change it to oData.GetData(&v1,&v2,&v3) to
    tell it to pass
    in addresses.

    That is how it works for C, yes. In VBScript the called method specifies
    how it wishes to receive an argument, and its passed accordingly.

    The raw SetData and GetData functions are not quite quite "copies of each other"

    :-) If they where I would not have written those twice. I'm a (hobby) programmer, and as such lazy by definition. :-)

    The "sting" is in the part after it, "just in the other direction" (one
    accepts data, the other returns it). Maybe "mirror copies" would have been
    a better description.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Wed Aug 16 20:46:07 2023
    JJ,

    That should be defined as:

    HRESULT GetData([in, out] float* val1,[in, out] float* val2,[in, out]
    float* val3);

    When I tried that (and just now re-tried to make sure) it gave me the same "type mismatch" error (not even trying to execute the OCX methods code)

    Otherwise, the function will get the pointer to the copy of the
    given values.

    First, the VBScript doesn't even get that far. It rejects the call itself.

    Second, why the copy ? As far as I can tell the translation layer
    /should/ be able to just point into the provided variant, setting its type
    to the one specified in the IDL description and just let the OCX code write, thru the pointer, whatever it wants into it.

    And as I mentioned in my remark section, changing the type from"float*" to "variant*" suddenly gets everything to work, even though I have just "[out]" and not "[in, out]"

    IOW, this works:

    HRESULT GetData([out] variant* val1,[out] variant* val2,[out] variant*
    val3);

    but this doesn't.

    HRESULT GetData([out] float* val1,[out] float* val2,[out] float* val3);

    and I do not see any reason why.


    .... :-(

    I just noticed in my initial post that I in the "GetData" definition used "[in]" where I should (ofcourse) have said "[out]" - I copy-pasted the (anonimized) "SetData" definition and changed its name but forgot to do the same with its direction. :-|

    My apologies.

    IDL example for a method which uses its multiple arguments as output is
    the IWebBrowserApp::ClientToWindow, which is defined in SHDOCVW.DLL's
    type library.

    This is the IDLs information of the the first argument of that IWebBrowserApp::ClientToWindow method:

    TypeDesc : 001A - PTR 00000000 0016 - INT
    ParamDesc : 0003 - IN OUT

    This is the first argument of my GetData method (using your in, out)

    TypeDesc : 001A - PTR 00000000 0004 - R4 (Float)
    ParamDesc : 0003 - IN OUT

    The only difference seems to be Int versus Float

    I rewrote my GetData definition to exactly mimic the ClientToWindow one

    TypeDesc : 001A - PTR 00000000 0016 - INT
    ParamDesc : 0003 - IN OUT

    , but it still fails. I would like to have been able to test that ClientToWindow, but I have no idea how/where to use it. Do you happen to
    know of some certain-to-work bit of VB script ?

    ... Currently I'm starting to get the feeling that VBScript refuses any "by reference" argument type, but for a variant (and possibly a BStr. Haven't tested that one yet).

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)