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

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

时间: 2025-01-20 07:57:02

把JS、vbs中的数组传递给COM组件Activex的相关文章

php-ajax 从页面中获取元素传递给PHP 进行数据库查询的问题

问题描述 ajax 从页面中获取元素传递给PHP 进行数据库查询的问题 ajax从界面中获取id为username的文本内容"张三" $.ajax({ type:"POST", url:"getallleads.php", data:"account="+$("#username").text(), success:function(data){showalllead(data);} }) PHP中接收,并

PHP数组传递给JavaScript以及json_encode的gbk中文乱码的解决

 代码如下 复制代码 /**************************************************************  * *    使用特定function对数组中所有元素做处理 *    @param    string    &$array        要处理的字符串 *    @param    string    $function    要执行的函数 *    @return boolean    $apply_to_keys_also       

如何将报表中的参数传递给VB

       在做机房收费系统周结账单的时候,需要将DTPicker中输入的日期变化的输入到GRDisplayviewer中,这时候需要在GRDisplayviewer中加入参数,并可以在VB中使用,下面展示一下过程: 在报表中右侧找到参数集合插入参数: 插入的参数如下: 然后在显示时间的地方这样写: 双击综合文本框: 点击插入域: 选择所需要的参数 如图所示,在报表中插入了参数 下面在VB中添加代码就可以利用了:  此过程是将日期时间控件中的值传递给报表中的参数: <span style=&quo

把ASP应用中的Session传递给asp.net应用

asp.net|session 最近做一个业务处理系统,因为它原有的用户系统使用ASP开发,在新的业务系统中使用了ASP.NET,ASP.NET APPLICATION要使用原来的ASP用户系统,于是问题出现了,ASP APPLICATION怎样才能让用户登录的状态及用户信息在ASP.NET中依然有效呢.于是我们考虑用构造FORM来自动提交传递ASP应用中的Session变量.例子如下ASP应用URL为http://127.0.0.1/asp/,并在ASP.NET应用中的web.config设定

VBS ArrayList Class vbs中的数组类_vbs

Class ArrayList  Private items()  Private size   Private Sub Class_Initialize  size = 0  ReDim items(1)   End Sub   Private Sub Class_Terminate  items = null   End Sub  Public Function Add(ByVal value)        If (size = Ubound(items)) Then EnsureCapa

怎样获取表格中某一行的数值作为参数传递给js

问题描述 怎样获取表格中某一行的数值作为参数传递给js 循环输出数据库中的数据,舌根成为能够一个表格,对某一行进行修改后,如何获取input的值并作为参数传递到js中,困扰好多天了,求大神帮忙 解决方案 当然你可以给每一行设置onclick事件,写一个function,里面传递这一行的input值过去,你就可以在函数里进行处理! 解决方案二: 修改时增加隐藏域,用隐藏域传值给后台

asp.net如何将后台c#数组传给前台js?

 如何把后台的c#数组传给前端的js,所以这个问题困扰了很久,后来在一篇文章中看到解决办法,文章中的方法处理的是定长数组,我现在处理的是不定长的,所以我又在文章的基础上修改了一下.自己亲自的实践了一下并应用在自己的程序中,果然解决了问题.现在结合大牛的文章和我自己的亲身实践来说明一下这个问题是如何解决的.     第一步:定义cs数组 cs文件里后台程序中要有数组,这个数组要定义成公共的数组. public string[] lat = null; public string[] lng = n

如何将php数组或者对象传递给javascript

 这篇文章主要介绍了将php数组或者对象传递给javascript的方法,需要的朋友可以参考下 在网上搜了一些方法,最后自己采用的是通过json字串的方式.    假设有一个php 数组 $arr,代码如下:  代码如下: <script> // html5中默认的script是javascript,故不需要特别指定script language  var arr_js = <?php echo json_encode($arr)?>;  </script>     

js怎么在function间传二维数组

问题描述 js怎么在function间传二维数组 我在一个function中定义了一个二维数组,想将这个二维数组当做参数传给另一个function ,怎么操作,求代码!!! 解决方案 请参考以下链接 JavaScript问题.能否在JS函数之间互相传递二维数组?http://zhidao.baidu.com/link?url=dogQO63WK_tuXcaCKurqCarVF41pMbtqWKqSau1eJ7aKvK9acNaiX9gG6p6RcmgOnD4fLzStn_QusvWG2M4DKq