把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;}
在脚本中建立数组并调用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;}
相关文章推荐
- 把javascript,vbscript中得数组传递给COM组件(or Activex)
- 把javascript,vbscript中得数组传递给COM组件(or Activex)
- 把javascript,vbscript中得数组传递给COM组件(or Activex)
- 把javascript,vbscript中得数组传递给COM组件(or Activex)
- vbscript与javascript传递变量
- vbscript与javascript传递变量
- javascript数组与php数组的地址传递及值传递用法实例
- 关于VBScript 与 JavaScript如何传递变量的详细研究!
- 关于javascript数组与VB DLL中中数组的传递问题
- php实现向javascript传递数组的方法
- Javascript数组中的按值传递
- 【JavaScript】jQuery+ajax传递json数组(局部响应处理)
- javascript数组与php数组的地址传递及值传递用法实例
- Javascript小知识点(七):数据类型赋值,浅拷贝,深拷贝(数组值传递还是引用传递)
- PHP和Javascript传递数组参数的方法
- COM组件开发笔记--字符串数组的传递
- 关于vbscript 与 javascript如何传递变量(包括服务器端与客户端)
- 如何将php数组或者对象传递给javascript
- 如何将服务器端计算出的数组传递到客户端的JavaScript?
- COM组件开发笔记--字符串数组的传递