您的位置:首页 > Web前端 > JavaScript

把javascript,vbscript中得数组传递给COM组件(or Act

2008-04-27 16:30 405 查看
COM组件的方法在IDL中的声明:[id(1), helpstring("方法InputArray")] HRESULT InputArray([in] VARIANT vData);
在脚本中建立数组并调用COM组件的方法:当数组很大的时候,like 100k ,javascript在给数组赋值的时候效率非常低!完成时间,cpu占用率,占用的内存都大的可怕。反而COM" target=_blank>vbscript却完成的很好。

COM组件的代码:从代码中可以看到COM" target=_blank>vbscript传进来的是个SafeArray。而javascript的情况就复杂了,javascript中得数组并不是真正意义上的数组,这个“数组”传到COM中被放进一个集合里,参数VARIANT的类型被置为VT_DISPATCH,我们得通过这个IDispatch指针调用invoke才能得到用来读取集合的枚举接口。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 COM" target=_blank>vbscript array hr = VariantArrayToBytes(&vData, &p, &nLen) ; }
if( S_OK == hr) { //....... do 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;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: