To pass an array of JS and VBS to COM component ActiveX

Source: Internet
Author: User
Tags javascript array

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;


}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.