在讲述如何在COM中获取JavaScript数组大小的代码之前,我们需要了解COM接口与JavaScript对象之间的交互机制。COM(Component Object Model)是微软提出的一个用于软件组件之间通信的系统。在COM中,接口是用以定义一组函数、属性和事件的机制,而JavaScript通常被用作网页中的脚本语言。当JavaScript需要调用COM组件时,就需要将JavaScript中的对象传递给COM接口。 当JavaScript调用COM接口传递数组时,COM接口端接收到的是一个VARIANT类型对象。VARIANT是一种特殊的数据类型,在COM编程中用于存储不同类型的数据。VARIANT对象可以包含多种基本数据类型,也可以包含如IDispatch的指针类型。IDispatch接口是COM中的一个特殊接口,它提供了一种机制,使得COM组件能够向脚本语言提供接口,这对于动态语言如JavaScript来说至关重要。 JavaScript中的数组对象是内建的,可以通过length属性来获取数组的大小。因此,当COM组件接收到一个数组时,它需要通过某种方式来获取这个JavaScript数组的length属性。 在COM中获取JavaScript数组大小的过程涉及几个关键步骤: 1. 使用GetIDsOfNames函数获取length属性的DISPID(dispatch ID)。 2. 使用Invoke函数通过得到的DISPID调用length属性来获取数组大小。 3. 将获取到的值转换为int类型。 获取数组大小的代码如下: ```cpp BSTR bstrLength = SysAllocString(L"length"); DISPID dispid; hr = lpDispatch->GetIDsOfNames(IID_NULL, &bstrLength, 1, LOCALE_USER_DEFAULT, &dispid); if (SUCCEEDED(hr)) { CComVariant varResult; hr = lpDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varResult, NULL, NULL); if (varResult.vt == VT_I4) { nLength = varResult.intVal; } } SysFreeString(bstrLength); ``` 在这段代码中,首先声明了一个BSTR类型的变量bstrLength来表示字符串“length”,接着使用GetIDsOfNames函数来获取对应属性名的DISPID。通过lpDispatch指针调用Invoke函数,并将DISPID作为参数传递进去,通过DISPATCH_PROPERTYGET标志位来获取属性值。如果成功,将通过varResult来接收返回值,并通过vt成员来判断其类型是否为VT_I4,即4字节整型。如果是,则将此值赋给nLength,这便是数组的长度。 获取到数组长度后,可以通过一个循环来遍历JavaScript数组中的每一个元素: ```cpp for (int i = 0; i < nLength; ++i) { CComVariant vaIndex(i, VT_I4); vaIndex.ChangeType(VT_BSTR); DISPID dispid; hr = lpDispatch->GetIDsOfNames(IID_NULL, &vaIndex.bstrVal, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { continue; } CComVariant varResult; hr = lpDispatch->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varResult, NULL, NULL); VARTYPE vt = varResult.vt; if (vt == VT_DISPATCH) { InvokeArray(varResult); continue; } hr = varResult.ChangeType(VT_BSTR); CComBSTR bstrVal = varResult.bstrVal; } ``` 在这段代码中,使用CComVariant来创建一个代表数组索引的变量vaIndex,并将其类型设置为VT_I4(4字节整型)。然后将该索引通过GetIDsOfNames获取对应属性的DISPID,并通过Invoke函数获取对应的属性值。如果返回的属性值是VT_DISPATCH类型,说明该元素是另一个JavaScript对象。如果不是,将值的类型转换为VT_BSTR(BSTR类型),并获取其BSTR值。 之所以这种方法优于使用SAFEARRAY,是因为SAFEARRAY在MIDL(Microsoft Interface Definition Language)中不被支持,且JavaScript对象本身也不支持SAFEARRAY。使用SAFEARRAY需要在VBScript和JavaScript之间切换,这会增加程序编写的复杂性和维护的难度。直接使用JavaScript数组对象,可以通过上述方法直接与COM接口交互,这不仅简化了过程,还避免了类型不兼容的问题。同时,JavaScript对象具有类型信息,可以作为C语言中结构体的替代方式,便于各种类型的数组或复杂数据结构的传递。
- 粉丝: 11
- 资源: 945
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助