快速业务通道

把JS、vbs中的数组传递给COM组件Activex

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

COM组件的方法在IDL中的声明:

[id(1), helpstring("方法InputArray")] HRESULT InputArray([in] VARIANT vData);

在脚本中建立数组并调用COM组件的方法:

当数组很大的时候,like 100k ,javascript在给数组赋值的时候效率非常低!完成时间,cpu占用率,占用的内存都大的可怕。反而VBScript却完成的很好。

COM组件的代码:

从代码中可以看到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 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 wo***ng.
  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)n

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号