Discussion:
OCX (ActiveX) returning of multiple floats
(too old to reply)
R.Wieser
2023-08-16 11:22:54 UTC
Permalink
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
Paul N
2023-08-16 13:55:59 UTC
Permalink
Post by R.Wieser
Hello all,
I've got an OCX/ActiveX object which has a method which is, in the IDL file,
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
HRESULT GetData([in] float* val1,[in] float* val2,[in] float* val3);
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.
Post by R.Wieser
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.
R.Wieser
2023-08-16 15:24:01 UTC
Permalink
Paul,
Post by Paul N
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 ...
Post by Paul N
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.
Post by Paul N
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
JJ
2023-08-16 15:15:05 UTC
Permalink
Post by R.Wieser
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.
JJ
2023-08-16 15:18:46 UTC
Permalink
Post by JJ
Post by R.Wieser
HRESULT GetData([in] float* val1,[in] float* val2,[in] float* val3);
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
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.
R.Wieser
2023-08-16 18:46:07 UTC
Permalink
JJ,
Post by JJ
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)
Post by JJ
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.
Post by JJ
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

Loading...