已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在COM中使用数组参数-SafeArray关键字:DCOM、数组、自定义类型、Marshal、SafeArray、ICollection1 使用SafeArraySafeArray是VB中的数组存储方式。通过SafeArray,可以在VC+和VB间相互调用。SafeArray也是Automation中的标准数组存储方式。1.1 SafeArray处理函数COM提供了一套API用于处理SafeArray。为了保证程序和SafeArray结构无关1,程序中建立、读取、更改和释放SafeArray都应该通过这些API进行,而不应该直接读写SafeArray结构。下面介绍常用的SafeArray处理函数。1.1.1 建立SafeArraySAFEARRAY* SafeArrayCreate( VARTYPE vt, unsigned int cDims, SAFEARRRAYBOUND * rgsabound);SAFEARRAY SafeArrayCreateEx( VARTYPE vt, unsigned int cDims, SAFEARRRAYBOUND * rgsabound PVOID pvExtra);SAFEARRAY* SafeArrayCreateVector( VARTYPE vt, long lLbound, unsigned int cElements);SAFEARRAY* SafeArrayCreateVectorEx( VARTYPE vt, long lLbound, unsigned int cElements, LPVOID pvExtra);SafeArrayCreate于建立多维普通数组。SafeArrayCreateEx用于建立多维自定义类型或接口指针数组。SafeArrayCreateVector用于建立一维普通数组。SafeArrayCreateVectorEx用于建立一维自定义类型或接口指针数组。1.1.2 释放数组HRESULT SafeArrayDestroy( SAFEARRAY * psa );SafeArrayDestroy用于释放创建的SafeArray数组。1.1.3 访问数据HRESULT SafeArrayAccessData( SAFEARRAY * psa, void HUGEP * ppvData);HRESULT SafeArrayUnaccessData( SAFEARRAY * psa);SafeArrayAccessData函数返回数组的指针。而SafeArrayUnaccessData释放通过SafeArrayAccessData所取得的指针。1.2 SafeArray相关处理1.2.1 创建SafeArray数组创建SafeArray可以使用COM提供的四个创建函数之一。所有的创建函数都返回一个SafeArray指针。通过这个指针可以读写SafeArray中的数据。SafeArray使用完后必须释放。1. SafeArrayCreateVectorSAFEARRAY* SafeArrayCreateVector( VARTYPE vt, long lLbound, unsigned int cElements );这个函数用来创建简单类型的一维数组。这个函数有三个参数:vt是数组类型、lLbound是数组下界值(最小下标)和数组长度。vt的取值如下表:vt值类型VT_UI1无符号1字节整数(BYTE)数组VT_UI2无符号2字节整数(WORD)数组VT_UI4无符号4字节整数(DWORD)数组VT_UINT无符号整数(UINT)数组VT_INT有符号整数(INT)数组VT_I1有符号1字节整数数组VT_I2有符号2字节整数数组VT_I4有符号4字节整数数组VT_R4IEEE 4字节浮点数(float)数组VT_R8IEEE 8字节浮点数(double)数组VT_CY8字节定点数货币值数组VT_BSTRVB字符串数组VT_DECIMAL12字节定点数(大数字)数组VT_ERROR标准错误编号数组VT_BOOL布尔值数组VT_DATE日期型数组VT_VARIANTVB Variant类型数组lLbound是数组的最小下标,可以是取负数。cElements是数组的长度。数组的最大下标的值是最小下标加上数组长度减一。SafeArrayCreateVector函数返回SafeArray结构的指针。2. SafeArrayCreateVectorExSAFEARRAY* SafeArrayCreateVectorEx( VARTYPE vt, long lLbound, unsigned int cElements, LPVOID pvExtra );这个函数用于创建自定义类型或COM对象的SafeArray数组。和SafeArrayCreateVector类似,SafeArrayCreateVector也有类型、下界和长度的三个参数。SafeArrayCreateVectorEx还增加了一个参数pvExtra。pvExtra的含义和vt的取值有关。当vt的取值在上表中的时候,pvExtra的取值没有作用。当vt取值VT_RECORD时,SafeArrayCreateVectorEx返回一个自定义类型(结构structure或联合union)的数组。这时,pvExtra必须是一个指向IRecordInfo的指针。当vt取值是VT_UNKNOWN或VT_DISPATCH时。pvExtra是一个指向IID(接口GUID)的指针。在目前的COM规范中,pvExtra只能是IID_IUnknown和IID_IDispatch。并且必须和vt的取值一致。a. 创建自定义类型数组当vt是VT_RECORD时。pvExtra必须是一个IRecordInfo指针。绝大多数情况下,我们从TLB中取得自定义类型的IRecordInfo指针。以下是取得IRecordInfo的代码:IRecordInfo * pRecordInfo;hr = GetRecordInfoFromGuids(LibID,MajorVer,MinorVer,LOCALE_USER_DEFAULT, TypeGUID,&pRecordInfo);上述代码中,LibID是所TLB的GUID,MajorVer和MinorVer分别是TLB的主、次版本号,TypeGUID是自定义结构的GUID。函数返回的是IRecordInfo接口的指针。b. 创建COM对象数组当需要创建COM数组时,可以使用IUnknown指针,也可以用IDispatch指针。如果需要使用其它指针类型,应该使用QueryInterface方法取得,而不能直接在数组中保存。因为SafeArray数组的序列化程序只能处理IUnknown和IDispatch两种指针类型,如果在数组中放其它接口类型的指针,可能在跨套间使用中会出现问题。1.2.2 读取和写入SafeArray数组。读写SafeArray数组时。应该使用COM提供的标准API。COM提供了大量函数用于SafeArray数组的操作,本文中仅使用其中的两个函数,SafeArrayAccessData和SafeArrayUnaccessData,和一些辅助用的函数。实际上是用这两个函数就可以进行所有的数组操作了。其它的函数用于对单个元素的操作,由于使用不多,而且效率也不高,所以本文中不进行说明。1. SafeArrayAccessData这个函数用于获取SafeArray的数据指针,并锁定SafeArray数组的数据。在取得了数据指针之后,就可以直接访问SafeArray数组中的数据了。如果数组类型是Type,那么所取得的数据指针实际上就是Type类型的数组的地址。在多维数组的情况下,必须把多个维度的下标转换成一维下标进行访问。2. SafeArrayUnaccessData这个函数的作用是对SafeArray数据解锁,解锁后,就不应该继续对数据指针进行读写访问。如果要访问,必须重新获取并锁定数据。3. 确定数组结构在访问数组之前,必须知道数组中数据的类型,、维数以及每个维度的下界和长度。COM提供了取得这些数组参数的函数。取得类型,返回“VT_”开头的类型枚举值:HRESULT SafeArrayGetVartype ( SAFEARRAY * pSA, VARTYPE * pVarType);取得维数,返回数组的维数:UINT SafeArrayGetDim ( SAFEARRAY * pSA);取得每个维度的属性,返回指定维数(nDim)的上界和下界(nDim从1开始):HRESULT SafeArrayGetLBound ( SAFEARRAY * pSA, UINT nDim, long * pLBound);HRESULT SafeArrayGetUBound ( SAFEARRAY * pSA, UINT nDim, long * pUBound);取得自定义类型接口,对于自定义结构数组,返回自定义结构类型数据的指针:HRESULT SafeArrayGetRecordInfo ( SAFEARRAY * pSA, IRecordInfo * ppRecordInfo);4. 访问普通一维数组从SafeArrayAccessData返回的指针实际上就是C语言中的一维数组地址。在VC+中可以像访问普通数组一样读写这个数组。需要注意的是,在C语言中,所有的数组下标都是从0开始的。而在SafeArray中,数组下标可以从任何数字开始。所以在访问前必须进行转换。转换方法就是从SafeArray的下标中减去数组的下界,就可以得到C语言中数组的下标了。如下:Type * pData;long LBound;SafeArrayAccessData(pSA, (void HUGEP *) &pData);SafeArrayGetLBound(pSA, 1, &LBound);Type Item = pDatan LBound;5. 访问多维数组访问多维数组和访问一维数组类似,只是要把多维下标转换成一维下标。把多维下标转换成一维下标的方法和在数组指针中介绍的是相似的。设:有n个维度,每个维度的长度(上界减去下界加一)分别是L1、L2、Ln。要转换的下标是X1、X2、Xn。可以根据下述公式转换成一维数组的下标。X1+X2*L1+X3*(L1*L2)+X4*(L1*L2*L3)+Xn*(L1*L2*L(n-1)6. 访问自定义结构数组访问自定义结构数组的时候,可以使用#iimport自动生成或者IDL编译产生的类型定义。如果没有办法取得自定义结构的声明,可以使用IRecordInfo接口中的方法间接访问自定义结构。首先需要取得自定义结构的长度,这可以通过IRecordInfo:GetSize方法取得。访问自定义结构中的字段内容,通过IRecordInfo:GetField和IRecordInfo:PutField方法实现。通过IRecordInfo中的其它方法还可以取得每个字段的属性内容。大家可以参考相关文档。1.2.3 释放SafeArray数组释放SafeArray数组应该通过COM的支持函数:HRESULT SafeArrayDestroy(SAFEARRAY * pSA);1.3 使用SafeArray的IDL定义每个接口都要通过IDL生成代理和占位程序代码。为了使代理和占位程序能够正确地对参数进行序列化,必须正确的书写IDL定义。MIDL工具直接支持SafeArray类型数据的传递。但是,在传递SafeArray数据的时候,必须通过SAFEARRAY的指针进行。困难在于,VC+ 6.0的添加方法和添加属性的工具不能够正确的处理SafeArray数组的情况。在IDL中,数组必须指定类型,如下:id(10) HRESULT Foo(in SAFEARRAY(LONG) pParam);在实现的函数声明中,要使用相应的指针类型:HRESULT Foo(SAFEARRAY * pParam);输出和输入输出类型的数组参数,在IDL中必须使用指针参数,而在函数声明中则是双重指针。id(11) HRESULT Foo2(out SAFEARRAY(LONG) * ppParam);函数声明如下:HRESULT Foo2(SAFEARRAY * ppParam);1.4 VARIANT和SafeArray在VB的接口中,经常通过VARIANT传递数组参数。这里简述一下使用VARIANT参数传递数组中需要注意的地方。1.4.1 输入数组对于输入数组,可以使用VARIANT指针,也可以使用VARIANT类型参数。在这两种情况下,VARIANT中的类型是不同的。当使用VARIANT指针时,输入的VARIANT参数的类型(vt参数的值)是VT_ARRAY | VT_BYREF | VT_xxx。此时,使用VARIANT参数的pparray字段取得SafeArray指针。如果参数是VARIANT,输入的VARIANT参数的类型(vt参数的值)是VT_ARRAY | VT_xxx。使用VARIANT参数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小儿铅中毒护理个案
- (完整版)制造企业计量器具管理体系及检定措施
- 物联网运维人员准则
- (完整版)市政亮化工程管理体系及运维措施
- 会议管理期末试题及答案
- 烟草专卖法律法规题库及答案
- 关节习惯性脱位护理查房
- 2026年快递公司分拣设备升级合同协议
- 脑淀粉样血管病护理查房
- 2026人教版小学一年级上册语文《金木水火土》完整教案
- 第4章 光谱表型分析技术
- 2026年劳务派遣管理员三级模拟通关提分题库含完整答案详解【必刷】
- 《数智化零售品类管理实务》课件-情境三 仓储会员店:人货场重构与价值逻辑
- 《PLC控制技术及应用》课件-知识延伸:常开常闭线圈使用延伸
- 芯片销售培训内容
- 廉洁知识教学课件
- 2026年无人机驾驶员ASFC考试题库完整
- 养老食品安全培训课件
- 2025年中国科学技术大学网络信息中心劳务派遣岗位招聘4人(公共基础知识)综合能力测试题附答案解析
- AIGC短视频策划与制作:AIGC短视频生成教学课件
- 肺结核合并肺心病护理查房
评论
0/150
提交评论