VARIANT variant_inp;COleSafeArray safearray_inp; long k=0;int len;BYTE rxdata[2048];CString strtemp;if(m_ctrlComm.GetCommEvent()){ case 2:{variant_inp=m_ctrlComm.GetInput();safearray_inp=variant_inp;len=safearray_inp.GetOneDimSize();for(k=0;k<len;k++){ safearray_inp.GetElement(&k,rxdata+k);}for(k=0;k<len;k++){BYTE bt=*(char*)(rxdata+k);strtemp.Format("%c",bt);m_strEditRXData+=strtemp;}}UpdateData(FALSE);
小弟只有10年VC++经验,帮你解读一下哦: 满意的话麻烦给我分. 如下代码是为了实现: 接收串口过来的数据! 首先初始化一个泛型类型接受容器, 接收串口接口发来的数据,然后显示在界面上的edit控件上!VARIANT variant_inp; 用VARIANT 泛型变量类型 定义一个数组变量variant_inp; 泛型就是任何类型都可以放进去的意思. 作为缓冲池使用很适合.COleSafeArray safearray_inp; 用COleSafeArray用OLE安全数据容器类 定义一个对象名字是 safearray inp 因为VARIANT虽然可以放任何类型数据到这个数组中,但该类型没有丰富的处理成员函数,说白了他是结构体不是类, 所以 需要做个转换, 转为COleSafeArray类型的数组类即可. 他具有非常丰富的成员函数.那么, 你会问为什么不直接让safearray_inp=m_ctrlComm.GetInput(); 读缓冲区,而要经过一个中间变量呢?variant_inp=m_ctrlComm.GetInput(); 读缓冲区safearray_inp=variant_inp; VARIANT转换成COleSafeArray型变量 VARIANT和COleSafeArray 是什么关系呢? 原因是: 这中间有调用不同的重载=运算符,m_ctrlComm.GetInput(); 的数据可以转化为variant_inp,有默认的转化方式,而safearray_inp=variant_inp则是另一个转化方式,如果直接转,可能数据不对。VARIANT和COleSafeArray 一个是结构体,一个是类,各自的数据构造不一样。long k=0; 初始化一个长整型变量 k=0;int len; 定义长度len,整数型.BYTE rxdata[2048]; 定义接受数据的数组,2k大小,2048字节. 为BYTE类型,也即unsigned char类型.CString strtemp; 定义一个CString类型的字符串strtemp;if(m_ctrlComm.GetCommEvent()) 如果控制通信对象m_ctlComm有get的事件发生,{------------------------这里应该加switch(ret) , 将上面getcommevent赋值给ret. case 2: 事件值为2表示接收缓冲区内有字符{variant_inp=m_ctrlComm.GetInput(); 控制通信器对象得到输入数据流. 如果GetCommEvent返回2,说明有字符到达了, 接收缓冲区内有字符safearray_inp=variant_inp; 将variant inp转换为COleSafeArray 类型,付给safearry inp. 因为COleSafeArray提供了丰富的函数处理.符合我们的需要.len=safearray_inp.GetOneDimSize(); 获取输入安全数组的长度lenfor(k=0;k<len;k++) 做个循环,{ safearray_inp.GetElement(&k,rxdata+k); 从输入的安全数组到rxdata进行数据拷贝. 一次一个字节拷贝.}for(k=0;k<len;k++) 做个循环. 读取len长度的所有字节.{BYTE bt=*(char*)(rxdata+k); 内存 rxdata 起始地址+k字节偏移的指针 取值,得到 一个字节. strtemp.Format("%c",bt); strtemp赋值为bt,也就是一个字符.m_strEditRXData+=strtemp; m_strEdit这个CEdit控件显示一直加长.}}UpdateData(FALSE); 将内存变量数据更新到界面.====================参考:VARIANT C++、BASIC、Java、Pascal、Script......计算机语言多种多样,而它们各自又都有自己的数据类型,COM 产生目的,其中之一就是要跨语言(注3)。而 VARIANT 数据类型就具有跨语言的特性,同时它可以表示(存储)任意类型的数据。从C语言的角度来讲,VARIANT 其实是一个结构,结构中用一个域(vt)表示------该变量到底表示的是什么类型数据,同时真正的数据则存贮在 union 空间中。结构的定义太长了(虽然长,但其实很简单)大家去看 MSDN 的描述吧,这里给出如何使用的简单示例:学生:我想用 VARIANT 表示一个4字节长的整数,如何做?老师:VARIANT v; v.vt=VT_I4; v.lVal=100;学生:我想用 VARIANT 表示布尔值“真”,如何做?老师:VARIANT v; v.vt=VT_BOOL; v.boolVal=VARIANT_TRUE;学生:这么麻烦?我能不能 v.boolVal=true; 这样写?老师:不可以!因为 类型 字节长度 假值 真值 bool 1(char) 0(false) 1(true) BOOL 4(int) 0(FALSE) 1(TRUE) VT_BOOL 2(short int) 0(VARIANT_FALSE) -1(VARIANT_TRUE) 所以如果你 v.boolVal=true 这样赋值,那么将来 if(VARIANT_TRUE==v.boolVal) 的时候会出问题(-1 != 1)。但是你注意观察,任何布尔类型的“假”都是0,因此作为一个好习惯,在做布尔判断的时候,不要和“真值”相比较,而要与“假值”做比较。学生:谢谢老师,你太牛了。我对老师的敬仰如滔滔江水,连绵不绝......学生:我想用 VARIANT 保存字符串,如何做?老师:VARIANT v; v.vt=VT_BSTR; v.bstrVal=SysAllocString(L"Hello,你好");学生:哦......我明白了。可是这么操作真够麻烦的,有没有简单一些的方法?老师:有呀,你可以使用现成的包装类 CComVariant、COleVariant、_variant_t。比如上面三个问题就可以这样书写:CComVariant v1(100),v2(true),v3("Hello,你好"); 简单了吧?!(注4)学生:老师,我再问最后一个问题,我如何用 VARIANT 保存一个数组?老师:这个问题很复杂,我现在不能告诉你,我现在告诉你怕你印象不深......(注5)学生:~!@#$%^&*()......晕!VARIANT 数据类型在文件OAIDL.IDL中定义如下: struct tagVARIANT { union { struct __tagVARIANT { VARTYPE vt; WORD wReserved1; WORD wReserved2; WORD wReserved3; union { ULONGLONG ullVal; LONGLONG llVal; LONG lVal; BYTE bVal; SHORT iVal; FLOAT fltVal; DOUBLE dblVal; VARIANT_BOOL boolVal; _VARIANT_BOOL bool; SCODE scode; CY cyVal; DATE date; BSTR bstrVal; IUnknown * punkVal; IDispatch * pdispVal; SAFEARRAY * parray; BYTE * pbVal; SHORT * piVal; LONG * plVal; LONGLONG * pllVal; FLOAT * pfltVal; DOUBLE * pdblVal; VARIANT_BOOL *pboolVal; _VARIANT_BOOL *pbool; SCODE * pscode; CY * pcyVal; DATE * pdate; BSTR * pbstrVal; IUnknown ** ppunkVal; IDispatch ** ppdispVal; SAFEARRAY ** pparray; VARIANT * pvarVal; PVOID byref; CHAR cVal; USHORT uiVal; ULONG ulVal; INT intVal; UINT uintVal; DECIMAL * pdecVal; CHAR * pcVal; USHORT * puiVal; ULONG * pulVal; ULONGLONG * pullVal; INT * pintVal; UINT * puintVal; struct __tagBRECORD { PVOID pvRecord; IRecordInfo * pRecInfo; } __VARIANT_NAME_4; } __VARIANT_NAME_3; } __VARIANT_NAME_2; DECIMAL decVal; } __VARIANT_NAME_1; };