MSComm控件编程中的几种数据类型,VARIANT数据类型,COleVariant colevariant

以下内容参考自MSDN和百度百科

1.VARIANT and VARIANTARG

是一个结构体。结构体中vt变量指明这个结构体封装的哪种类型。结构体重包含了一个Union。该联合体根据vt的类型不同而不同。比如:vt为VT_UI1代表联合体是unsignedchar.

Use VARIANTARG to describe arguments passed within DISPPARAMS,and VARIANT to specify variant data that cannot be passed byreference. When a variant refers to another variant by using theVT_VARIANT | VT_BYREF vartype, the variant being referred to cannotalso be of type VT_VARIANT | VT_BYREF. VARIANTs can be passed byvalue, even if VARIANTARGs cannot. The following definition ofVARIANT is described in OAIDL.H automation headerfile:

typedef struct FARSTRUCT tagVARIANT VARIANT;typedef struct FARSTRUCT tagVARIANT VARIANTARG;typedef struct tagVARIANT  {   VARTYPE vt;   unsigned short wReserved1;   unsigned short wReserved2;   unsigned short wReserved3;   union {      Byte                    bVal;                 // VT_UI1.      Short                   iVal;                 // VT_I2.      long                    lVal;                 // VT_I4.      float                   fltVal;               // VT_R4.      double                  dblVal;               // VT_R8.      VARIANT_BOOL            boolVal;              // VT_BOOL.      SCODE                   scode;                // VT_ERROR.      CY                      cyVal;                // VT_CY.      DATE                    date;                 // VT_DATE.      BSTR                    bstrVal;              // VT_BSTR.      DECIMAL                 FAR* pdecVal          // VT_BYREF|VT_DECIMAL.      IUnknown                FAR* punkVal;         // VT_UNKNOWN.      IDispatch               FAR* pdispVal;        // VT_DISPATCH.      SAFEARRAY               FAR* parray;          // VT_ARRAY|*.      Byte                    FAR* pbVal;           // VT_BYREF|VT_UI1.      short                   FAR* piVal;           // VT_BYREF|VT_I2.      long                    FAR* plVal;           // VT_BYREF|VT_I4.      float                   FAR* pfltVal;         // VT_BYREF|VT_R4.      double                  FAR* pdblVal;         // VT_BYREF|VT_R8.      VARIANT_BOOL            FAR* pboolVal;        // VT_BYREF|VT_BOOL.      SCODE                   FAR* pscode;          // VT_BYREF|VT_ERROR.      CY                      FAR* pcyVal;          // VT_BYREF|VT_CY.      DATE                    FAR* pdate;           // VT_BYREF|VT_DATE.      BSTR                    FAR* pbstrVal;        // VT_BYREF|VT_BSTR.      IUnknown                FAR* FAR* ppunkVal;   // VT_BYREF|VT_UNKNOWN.      IDispatch               FAR* FAR* ppdispVal;  // VT_BYREF|VT_DISPATCH.      SAFEARRAY               FAR* FAR* pparray;    // VT_ARRAY|*.      VARIANT                 FAR* pvarVal;         // VT_BYREF|VT_VARIANT.      void                    FAR* byref;           // Generic ByRef.      char                    cVal;                 // VT_I1.      unsigned short          uiVal;                // VT_UI2.      unsigned long           ulVal;                // VT_UI4.      int                     intVal;               // VT_INT.      unsigned int            uintVal;              // VT_UINT.      char FAR *              pcVal;                // VT_BYREF|VT_I1.      unsigned short FAR *    puiVal;               // VT_BYREF|VT_UI2.      unsigned long FAR *     pulVal;               // VT_BYREF|VT_UI4.      int FAR *               pintVal;              // VT_BYREF|VT_INT.      unsigned int FAR *      puintVal;             //VT_BYREF|VT_UINT.   };};可以注意到,tagVARIANT结构体的一个成员是共用体union数据类型,
 union 共用体名{
  数据类型 成员名;
  数据类型 成员名;
  ...
  } 变量名;
  共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。
例如用上面说明的共用体定义一个名为bar的共用体变量, 可写成:
  union foo bar;
  在共用体变量bar中,整型变量i和字符变量c共用同一内存位置。
  当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。以上例而言,最大长度是double数据类型,所以foo的内存空间就是double型的长度。
  由于union的资料成员共用一个内存空间,所以必须存取正确的成员才能正确的读取变量值,可以使用一个额外的变数或列举型态来记录最后一次使用空间的是哪个成员,
 #include <iostream>using namespace std;union StateMachine {
   public:
  char character;  int number;
  char *str;
  StateMachine(char c) {
  character = c;
  }
  StateMachine(int n) {
  number = n;
  }
  StateMachine(char* s) {
  str = s;
  }
  };
  enum State {character, number, str};
  int main() {
  State state = character;
  StateMachine machine('J');
  ...
  if(state == character)
  cout << machine.character << endl;
  ...
  return 0;
  }
  另外要注意的是,union的成员不可以为静态、引用,如果是自订型态的话,该自订型态成员不可以有建构函式、解构函式或是复制指定运算子
2.COleVariant

COleVariant does not have a baseclass.此类没有基类,COleVariant类是对VARIANT结构的封装。它的构造函数具有极为强大的功能,当对象构造时首先调用VariantInit进行初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与VARIANT类型转换中为我们提供极大的方便。
A COleVariant object encapsulates the VARIANT data type. This data typeis used in OLE automation. Specifically, the DISPPARAMS structure contains apointer to an array of VARIANT structures. ADISPPARAMS structure is used to pass parameters to IDis--patch::Invoke.
NoteThisclass is derived from the VARIANT structure. This means youcan pass a COleVariant in a parameter that calls for aVARIANT and that the data members of the VARIANTstructure are accessible data members of COleVariant.
The two related MFC classes COleCurrency and COleDateTime encapsulate the variant data types CURRENCY(VT_CY) and DATE (VT_DATE). TheCOleVariant class is used extensively in the DAO classes;see these classes for typical usage of this class, for exampleCDaoQueryDef and CDaoRecordset.
For more information, see the VARIANT, CURRENCY, DISPPARAMS, and IDispatch::Invoke entries in theWin32 SDK OLE Programmer’s Reference.
For more information on the COleVariant class and its use inOLE automation, see "Passing Parameters in OLE Automation" in thearticle Automation in Visual C++Programmer’s Guide.

3.SAFEARRAY

  SAFEARRAY的主要目的是用于automation中的数组型参数的传递。因为在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray。实质上SafeArray就是将通常的数组增加一个描述符,说明其维数、长度、边界、元素类型等信息。SafeArray也并不单独使用,而是将其再包装到VARIANT类型的变量中,然后才作为参数传送出去。在VARIANT的vt成员的值如果包含VT_ARRAY|...,那么它所封装的就是一个SafeArray,它的parray成员即是指向SafeArray的指针。SafeArray中元素的类型可以是VARIANT能封装的任何类型,包括VARIANT类型本身。

  使用SafeArray的具体步骤:

  方法一:

  包装一个SafeArray:

  (1). 定义变量,如:

  VARIANT varChunk;

  SAFEARRAY *psa;

  SAFEARRAYBOUND rgsabound[1];

  (2). 创建SafeArray描述符:

  uIsRead=f.Read(bVal,ChunkSize);//readarray from a file.

  if(uIsRead==0)break;

  rgsabound[0].cElements =uIsRead;

  rgsabound[0].lLbound = 0;

  psa =SafeArrayCreate(VT_UI1,1,rgsabound);

  (3). 放置数据元素到SafeArray:

  for(longindex=0;index<uIsRead;index++)

  {

  if(FAILED(SafeArrayPutElement(psa,&index,&bVal)))

  ::MessageBox(NULL,"出毛病了。","提示",MB_OK| MB_ICONWARNING);

  }

  一个一个地放,挺麻烦的。

  (4). 封装到VARIANT内:

  varChunk.vt = VT_ARRAY|VT_UI1;

  varChunk.parray = psa;

  这样就可以将varChunk作为参数传送出去了。

  读取SafeArray中的数据的步骤:

  (1). 用SafeArrayGetElement一个一个地读

  BYTE buf[lIsRead];

  for(longindex=0;index<lIsRead;index++)

  {

  ::SafeArrayGetElement(varChunk.parray,&index,buf+index);

  }

  就读到缓冲区buf里了。

  方法二:

  使用SafeArrayAccessData直接读写SafeArray的缓冲区:

  (1). 读缓冲区:

  BYTE *buf;

  SafeArrayAccessData(varChunk.parray,(void **)&buf);

  f.Write(buf,lIsRead);

  SafeArrayUnaccessData(varChunk.parray);

  (2). 写缓冲区:

  BYTE *buf;

  ::SafeArrayAccessData(psa, (void**)&buf);

  for(longindex=0;index<uIsRead;index++)

  {

  buf=bVal;

  }

  ::SafeArrayUnaccessData(psa);

  varChunk.vt = VT_ARRAY|VT_UI1;

  varChunk.parray = psa;

  这种方法读写SafeArray都可以,它直接操纵SafeArray的数据缓冲区,比用SafeArrayGetElement和SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData(psa),否则会出错的。

  如果SafeArray中存的是BSTR的二维数组,则代码如下:

  if(varChunk.vt = VT_ARRAY |VT_BSTR)

  {

  BSTR* buf;

  long LBound; // 数组下界

  long UBound; // 数组上界

  SafeArrayAccessData(varChunk.parray,(void **)&buf);

  SafeArrayGetLBound(varChunk.parray,1, &LBound);

  SafeArrayGetUBound(varChunk.parray,1, &UBound);

  for(long i = LBound; i< UBound; i ++)

  {

  CString str(buf);

  MessageBox(str);

  }

  SafeArrayUnaccessData(varChunk.parray);

  }

4.COleSafeArray
COleSafeArray类是用于处理任意类型和维数的数组的类。COleSafeArray是从OLE VARIANT结构派生而来的。OLE SAFEARRAY成员函数在可以通过COleSafeArray来访问,就象是特别为一维的字节数组所设计的一个成员函数集。

Class COleSafeArray is a class for working with arrays ofarbitrary(任意的) type and dimension(维). COleSafeArray derivesfrom the OLE VARIANT structure.The OLE SAFEARRAY member functions are available throughCOleSafeArray, as well as a set of member functionsspecifically designed for one-dimensional arrays of bytes. 构造COleSafeArray 构造一个COleSafeArray对象

操作 Attach 给COleSafeArray对象以存在的VARIANT数组的控制

Clear 释放基VARIANT中的所有数据
Detach 将VARIANT数组从COleSafeArray对象中分离出来(这将使数据不会被释放)
Win32 API 包装 AccessData 获取一个指向数组数据的指针


AllocData 为数组分配内存
AllocDescriptor 为安全数组描述符分配内存
Copy 创建一个已存在的数组的拷贝
Create 创建一个安全数组
Destroy 销毁一个已经存在的数组
DestroyData 销毁一个安全数组中的数据
DestroyDescriptor 销毁一个安全数组的描述符
GetDim 返回数组的维数
GetElement 获取安全数组中的一个单一元素
GetElemSize 返回安全数组中一个元素的按字节表示的大小
GetLBound 返回一个安全数组任一维的下界
GetUBound 返回一个安全数组任一维的上界
Lock 增加一个数组的加锁计数,并将一个指向数组数据的指针放到数组描述符中
PtrOfIndex 返回一个指向被索引的元素的指针
PutElement 将一个单一的元素放入数组中
Redim 改变一个安全数组的最不重要(最右边)的边界
UnaccessData 减小一个数组的加锁计数,并使由AccessData获得的指针无效
Unlock 减小一个数组的加锁以使它能被释放或改变大小

一维数组操作 CreateOneDim 创建一个一维的COleSafeArray对象
GetOneDimSize 返回一个一维的COleSafeArray对象中的元素个数
ResizeOneDim 改变一个一维的COleSafeArray对象中的元素个数

操作符

operator =将一些值(包括SAFEARRAY,VARIANT,COleVariant,或COleSafeArray对象)拷贝到COleSafeArray对象中,自动将其他数据类型转换为COleSafeArray
operator == 比较两个不同的数组(SAFEARRAY,VARIANT,ColeVariant,或COleSafeArray对象)

operator <<Outputs the contentsof a COleSafeArray object to the dump context.
operator LPVARIANTAccesses the underlying VARIANT structure ofthe COleSafeArray object.
operator LPCVARIANTAccesses the underlying VARIANT structure ofthe COleSafeArray object.
构造函数
    COleSafeArray::COleSafeArray

COleSafeArray();
COleSafeArray( const SAFEARRAY& saSrc, VARTYPEvtSrc );
COleSafeArray( LPCSAFEARRAY psaSrc, VARTYPE vtSrc );
COleSafeArray( const COleSafeArray& saSrc );
COleSafeArray( const VARIANT& varSrc );
COleSafeArray( LPCVARIANT pSrc );
COleSafeArray( const COleVariant& varSrc );

参数: saSrc要被拷贝到新的COleSafeArray对象中去的已经存在的COleSafeArray对象或SAFEARRAY。
vtSrc 新的COleSafeArray对象的VARTYPE。
psaSrc 一个指向要被拷贝到新的COleSafeArray对象中去的SAFEARRAY的指针。
varSrc 要被拷贝到新的COleSafeArray对象中去的已经存在的VARIANT或者COleVariant。
pSrc 一个指向要被拷贝到新的COleSafeArray对象中去的VARIANT对象的指针。

说明:
所有这些构造函数都创建一个新的COleSafeArray对象。如果没有参数,则创建的是一个空的COleSafeArray对象(VT_EMPTY)。如果COleSafeArray是从另一个数组拷贝来的,并且这个数组的VARTYPE并不是完全确定的(一个COleSafeArray,COleVariant,或者VARIANT),则源数组中的VARTYPE被保留,并且不需要说明。如果COleSafeArray是从另一个数组拷贝而来,并且该数组的VARTYPE是不知道的,则VARTYPE必须用vtSrc参数来指定。
如果出错,则函数抛出一个CMemoryException或COleException。

  

爱华网本文地址 » http://www.413yy.cn/a/25101016/313947.html

更多阅读

酸枣仁的几种食用方法 酸枣仁怎样吃治失眠

酸枣仁的几种食用方法——简介酸枣仁有降低血压、安神镇静和调节神经的作用。据《本草图经》记载,“酸枣仁,主烦心不得眠”。把酸枣仁加入白米中煮成粥,老年人吃起来更容易消化吸收。因此,用酸枣仁、白米熬粥,治疗神经衰弱引起的失眠效果

小学生的几种学习方法

小学生学习方法介绍小学生的几种学习方法——工具/原料学法的掌握,如同知识的获得一样,有一个从无到有,从少到多,从不会到会的发展过程。开始,在很大程序上要靠教师在教给知识的过程中,主动明确的指点。诸如怎样发言答问,怎样执笔写字,怎样

家用不锈钢电水壶除垢的几种方法 电水壶除水垢

家用不锈钢电水壶除垢的几种方法——简介 不锈钢电水壶,作为一种常用家用小家电,在外山设计上并没有多少的特点,在使用过程中在常出现的现象就是在内壁上附着的水垢,不锈钢电水壶水垢,不仅会影响电水壶的使用效率,同时还对电水壶的使用寿

白凡士林治疗牛皮癣(银屑病)的几种方法介绍 银屑病治疗方法

一、什么是白凡士林白凡士林,WHITEVASELIN,是从石油中得到的多种烃的半固体混合物,为白色均匀的软膏状物;无臭或几乎无臭;与皮肤接触有滑腻感;具有一定的拉丝性。凡士林非常便宜,很多爱美的女士因此对它不屑一顾。事实上,与市场上其他更加

声明:《MSComm控件编程中的几种数据类型,VARIANT数据类型,COleVariant colevariant》为网友噯赱吢誶分享!如侵犯到您的合法权益请联系我们删除