当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:55:00  来源:本站整理

把JS、vbs中的数组传送给COM组件Activex[VC/C++编程]

赞助商链接



  本文“把JS、vbs中的数组传送给COM组件Activex[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

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 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;
}


  以上是“把JS、vbs中的数组传送给COM组件Activex[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 把JS、vbs中的数组传送给COM组件Activex
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .