Calling functions of COM object from JScript

After earlier post on instantiating COM class, let’s move ahead with invoking the functions over this COM object.

To be able to invoke functions on the instantiated COM function through JScript, we need to add the method to the ITest interface which is derived from IDispatch.

Lets start with a example of a COM function Func1 which takes 2 parameters and returns the product of two numbers.

First step is to add the method for ITest interface:

I added this through ATL wizard, its much simpler that way. Note that return value is indicated as retval.

[id(1), helpstring("method Func1")] HRESULT Func1([in] FLOAT a, [in] FLOAT b, [out,retval] FLOAT* result);

Implementing this function on Test class:

STDMETHODIMP CTest::Func1(FLOAT a, FLOAT b, FLOAT* result)

{

      *result = a * b;

      return S_OK;

}

To call this method from JScript now we just need to pass in the parameters and store the result the way we normally do in JScript.

var result = x.Func1(10, 20);

What if you wants the function that returns array. It becomes really tricky but here is how one can achieve it.

To start with we need to add a method to ITest that would have retVal of VARIANT*

[id(2), helpstring("method Func2")] HRESULT Func2([out,retval] VARIANT* arrayVal);

After this here is how we implement the SafeArray in the func2.

Creation of the array:

SAFEARRAY * psa;

SAFEARRAYBOUND rgsabound[1];

rgsabound[0].lLbound = 0;

rgsabound[0].cElements = 5;

psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);

Populating data within this array:

VARIANT HUGEP *pInteger;

SafeArrayAccessData(psa, (void HUGEP**)&pInteger);

for (int i = 0; i < psa->rgsabound->cElements; i++)

{

      pInteger[i].intVal = i;

      pInteger[i].vt = VT_INT;

}

SafeArrayUnaccessData(psa);

Now note that JScript can return or receive arrays of VARIANTs only. That was the reason the the method defined is with returnVal type of VARIANT.

VARIANT var;

var.vt = VT_ARRAY | VT_VARIANT;

var.parray = psa;

*arrayVal = var;

 

Now story does not end here. It is even more trickier to use this array in Jscript. The variable needs to be converted to VB array first and then we need to use toArray method on this to actually get JScript Array. Here is how:

var array1 = x.Func2();

var array2 = new VBArray(array1);

var actualArray = array2.toArray();

For more information on VARIANTs you can check out this MSDN link:

https://msdn2.microsoft.com/en-us/library/ms221627.aspx

There is also a nice post on MSDN for JScript Types and COM types at:

https://blogs.msdn.com/ericlippert/archive/2004/07/14/183241.aspx

Sample.zip