The method of the COM component is declared in IDL:
[ID (1), helpstring ("Method Inputarray")] HRESULT Inputarray ([in] VARIANT vdata);
Methods to establish an array in a script and invoke a COM component:
When the array is large, like 100k, JavaScript is very inefficient when assigning values to arrays! Completion time, CPU occupancy rate, memory consumption is terrible. Instead, VBScript did a good job.
Code for COM components:
You can see from the code that VBScript is passing in a SAFEARRAY. And JavaScript is complicated, and the group in JavaScript is not really an array, the "array" passed to COM is put into a set, the type of parameter variant is set to Vt_dispatch, We have to invoke invoke through this IDispatch pointer to get an enumeration interface to read the collection.
stdmethodimp Cbigparamctl::inputarray (VARIANT vdata)
{
Lpbyte p;
DWORD Nlen;
HRESULT HR;
if (vdata.vt = = Vt_dispatch)
{
//deal with JavaScript array
hr = variantenumtobytes (vdata.pdispval,&p, &nlen);
}
Else
{
//deal with VBScript array
hr = variantarraytobytes (&vdata, &p, &nlen);
}
if (S_OK = hr)
{
//... sth on P
delete[] p;
}
return S_OK;
}
HRESULT variantenumtobytes (idispatch* disp, lpbyte *ppbytes, DWORD *pdwbytes)
{
//DebugBreak ();
HRESULT HR;
Dispparams Noargs = {null, NULL, 0, 0};
CComVariant RESULTV;
hr = Disp->invoke (Dispid_newenum,
Iid_null,
Locale_system_default,
Dispatch_propertyget,
&noargs,
&RESULTV,
NULL,
NULL);
if (FAILED (HR) && FAILED (Resultv.changetype (vt_unknown))
return E_FAIL;
//Bug 37459, above Invoke succeeds, but returns RESULTV.VT = = Vt_empty, resultv->other param unchanged-
if (resultv.vt!= vt_unknown && resultv.vt!= vt_dispatch)
{
return E_FAIL;
}
ccomqiptr Penum (resultv.punkval);
if (!penum)
return E_FAIL;
//Count the elements
*pdwbytes = 0;
hr = S_OK;
//get Enum Size
while (hr = = S_OK)
{
hr = Penum->skip (1);
if (hr = S_OK)
(*pdwbytes) + +;
}
//allocate Memory
*ppbytes = (LPBYTE) new byte[*pdwbytes];
int ncount = 0;
CComVariant ELEMV;
Penum->reset ();
hr = S_OK;
while (hr = = S_OK)
{
//could switch to use Skip when Cary gets
//IT working.
hr = Penum->next (1, &ELEMV, NULL);
if (elemv.vt!= VT_I4)
hr = S_FALSE; Correct for Dispproxy bug 19307
Else
{
int ntmp = Elemv.lval;
(*ppbytes) [ncount] = (BYTE) ntmp;
}
if (hr = S_OK)
ncount++;
}
return S_OK;
}
HRESULT variantarraytobytes (VARIANT *pvariant, Lpbyte *ppbytes, DWORD *pdwbytes)
{
uses_conversion;
if (pvariant->vt!= (vt_variant | VT_BYREF))
return E_INVALIDARG;
if (!) ( PVARIANT->PVARVAL->VT & Vt_array))
return E_INVALIDARG;
safearray* PX = NULL;
if (PVARIANT->PVARVAL->VT & Vt_byref)
PX = * (Pvariant->pvarval->pparray);
Else
PX = pvariant->pvarval->parray;
if (:: Safearraygetdim (PX)!= 1)
return E_INVALIDARG;
*ppbytes = NULL;
*pdwbytes = 0;
VARIANT *parray = NULL;
HRESULT hr = E_FAIL;
_variant_t v;
hr = Safearrayaccessdata (PX, (void * *) &parray);
if (SUCCEEDED (HR))
{
*pdwbytes = px->rgsabound->celements;
*ppbytes = (LPBYTE) new byte[*pdwbytes];
for (DWORD i = 0; i < *pdwbytes; i++)
{
v = parray[i];
V.changetype (VT_UI1);
(*ppbytes) [i] = v.bval;
}
Safearrayunaccessdata (PX);
}
Else
return HR;
SafeArrayDestroy (PX);
return S_OK;
}