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

在路上197139

在路上197139

2016-02-19 17:40

今天图老师小编要向大家分享个把JS,vbs中的数组传递给COM组件,Activex教程,过程简单易学,相信聪明的你一定能轻松get!

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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

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

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  在脚本中建立数组并调用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;
}

展开更多 50%)
分享

猜你喜欢

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

编程语言 网络编程
把JS,vbs中的数组传递给COM组件,Activex

父母把自信传递给孩子

育儿知识 怀孕 孕妇
父母把自信传递给孩子

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

胎教:把快乐传递给宝宝

分娩
胎教:把快乐传递给宝宝

关于javascript数组与VB DLL中中数组的传递问题

Web开发
关于javascript数组与VB DLL中中数组的传递问题

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

1.14 ActiveX 组件

Web开发
1.14 ActiveX 组件

ASP ActiveX 组件

ASP
ASP ActiveX 组件

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

关于对话框

关于对话框

行业网站的运营以及赚钱方法

行业网站的运营以及赚钱方法
下拉加载更多内容 ↓