2024年10月colesafearray(高分求解串口返回的VARIANT与COleSafeArray的出现在致命错误!)

 更新时间:2024-10-12

  ⑴colesafearray(高分求解串口返回的VARIANT与COleSafeArray的出现在致命错误!

  ⑵高分求解串口返回的VARIANT与COleSafeArray的出现在致命错误!

  ⑶同时学习中。用ColeSafeArray经常会出现错误,我也没解决。我想问下,你是想操作字符串还是什么?如果是字符串可以用VARIANT的另外一个变量。VARIANTdata;data=m_ms.Getinput();CSringstring;string=data.bstrval;m_show+=string+“

  ⑷“;UpdateData(FALSE);//在文本框中显示数据。要是二进制数据的话,不出现字符,上面是行的。

  ⑸关于串口通信中COleSafearray的问题,怎么解决

  ⑹其实前面已经问过了,不过不能问题补充,所以再发一次答到的,其实加起来就是+分了,大家帮帮忙啊在编一个串口通信程序,因为刚上手,所以是按着龚建伟书的第一章改写的。在处理接收数据的函数中voidCSerTestDlg::Onm(){VARIANTvariant_inp;COleSafeArraysafearray_inp;LONGlen,k;BYTErxdata;CStringstrtemp;if(m_ctrlm.GetmEvent()==){variant_inp=m_ctrlm.GetInput();//第一步safearray_inp=variant_inp;//第二步len=safearray_inp.GetOneDimSize();//第三步for(k=;k《len;k++)safearray_inp.GetElement(&k,rxdata+k);for(k=;k《len;k++){charbt=*(char*)(rxdata+k);strtemp.Format(“%c“,bt);m_strEditRXData+=strtemp;UpdateData(FALSE);}}}我用debug查看,第一步的结果是对的,数据放入到我定义的缓冲区variant_inp中第二步弹出错误框,但忽略后safearray_inp也接收到数据第三步又弹出错误框,但忽略后得到的有效数据长度len是一个负数。结果后面就一直错下去了。请教一下大家是不是safearray_inp=variant_inp;出了什么问题,怎么改?ps:进一步调试后我发现似乎是COleSafeArray这个结构的问题不单只是safearray_inp=variant_inp的问题第二步改为safearray_inp.Attach(variant_inp)还是要报错。忽略后,我即使手动把len=safearray_inp.GetOneDimSize()改为len=在下面的程序中safearray_inp.GetElement(&k,rxdata+k)还是要报错。也就是说凡是涉及safearray_inp的都会出错。我想请教一下为什么,望不吝赐教ps:我试用了下面这种方法,但还是死在Safearray上voidCSerTestDlg::Onm(){COleVariantvarInput;COleSafeArraysafearray_inp;LONGlLen=;LONGi=;BYTErxdata;//设置BYTE数组An-bITintegerthatisnotsigned.//注意:设置接收数据if(==m_ctrlm.GetmEvent())//事件值为表示接收缓冲区内有字符{varInput.Attach(m_ctrlm.GetInput());//读缓冲区safearray_inp=varInput;//VARIANT型变量转换为ColeSafeArray型变量lLen=safearray_inp.GetOneDimSize();//得到有效数据长度for(i=;i《lLen;i++){safearray_inp.GetElement(&i,rxdata+i);//转换为BYTE型数组}m_strEditRXData+=(char*)rxdata;UpdateData(FALSE);//更新编辑框内容}

  ⑺关于串口通信中COleSafearray的问题

  ⑻#defineDIM#defineLENvoidCTestDlg::OnTest(){BYTEivTest[LEN]={,,,,,,,,};SAFEARRAYBOUNDsab[DIM];sab.cElements=LEN;sab.lLbound=;SAFEARRAY*psa=NULL;psa=SafeArrayCreate(VT_UI,DIM,sab);for(longi=;i《LEN;i++){SafeArrayPutElement(psa,&i,&(ivTest[i]));}VARIANTvt;vt.vt=VT_ARRAY|VT_UI;vt.parray=psa;COleSafeArraysa;sa=vt;DWORDdwLen=sa.GetOneDimSize();CStringstr;str.Format(“%d“,dwLen);MessageBox(str);}---------------------------------------------------------------------------------我写了这样的一个测试程序,感觉问题应该处在你的“第一步”,也就是说,你未必完全正确的从串口缓冲区获得了有效的VARIANT数据。

  ⑼单片机里IC温度传感器采集的温度如何传到上位机上位机怎么处理数据

  ⑽利用串口通讯将单片机采集的温度数据传给上位机,譬如上位机可以用VC++开发、上位机在串口接收数据事件中,可参考如下代码:voidCSmTestDlg::Onm(){ //TODO:Addyourcontrolnotificationhandlercodehere VARIANTvariant_inp; COleSafeArraysafearray_inp; LONGlen,k; BYTErxdata;//设置BYTE数组An-bitintegerthatisnotsigned. CStringstrtemp; if(m_ctrlm.GetmEvent()==)//事件值为表示接收缓冲区内有字符 { variant_inp=m_ctrlm.GetInput();//读缓冲区 safearray_inp=variant_inp;//VARIANT型变量转换为ColeSafeArray型变量 len=safearray_inp.GetOneDimSize();//得到有效数据长度 for(k=;k《len;k++) safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组 for(k=;k《len;k++)//将数组转换为Cstring型变量 { BYTEbt=*(char*)(rxdata+k);//字符型 strtemp.Format(“%d“,bt);//将字符送入临时变量strtemp存放 m_strRXData=strtemp;//加入接收编辑框对应字符串 } } UpdateData(FALSE);//更新编辑框内容}

  ⑾急!龚建伟关于串口通信的程序有问题的,期望高手解决!

  ⑿粗略的看了一下,你的代码没有问题,我怀疑是其他的地方出现了问题。给你一个我以前写的,模仿串口调试助手用串口控件的方法写的程序,你参考一下吧。代码已发到你的邮箱。补充:接收就是在Onm()函数里啊,你的这段代码没有什么问题。有没有做串口控件的事件映射啊:BEGIN_EVENTSINK_MAP(uteDlg,CDialog)ON_EVENT(uteDlg,IDC_MSM,/*Onm*/,Onm,VTS_NONE)END_EVENTSINK_MAP()如果有的话,那接收应该没有问题的。况且即使只有发没有收,那也不会点发送就会出错的。我发给你的代码你看到了吗,那是标准串口控件的用法,里面收发演示都有的,你详细看一下吧,应该是对你有所帮助的。有人说是因为龚建伟的串口初始化部分代码有问题,才导致了后面的安全数组出现错误。我一直是使用如下代码进行串口控件的初始化的,已经应用到过很多程序中没有出现过问题,你可以试试:if(m_ctrlm.get_PortOpen())m_ctrlm.put_PortOpen(FALSE);m_ctrlm.put_mPort();//选择//输出方式为二进制方式m_ctrlm.put_InputMode();//text,binary//m_ctrlm.put_InBufferSize();//m_ctrlm.put_OutBufferSize();m_ctrlm.put_Settings(“,n,,“);//波特率,无校验ndo,个数据位,个停止位if(!m_ctrlm.get_PortOpen())m_ctrlm.put_PortOpen(TRUE);//打开串口m_ctrlm.put_RThreshold();//参数表示每当串口接收缓冲区中有多于或等于个字符时将引发一个接收数据的Onm事件m_ctrlm.put_InputLen();//设置当前接收区数据长度为//---读接收缓冲区的所有内容//n---读接收缓冲区的n个字符(或二进制码)m_ctrlm.get_Input();//先预读缓冲区以清除残留数据这是VS中的代码,在VC.中请把函数前缀get_替换为Get、put_替换为Set

  ⒀小弟只有年VC++经验,帮你解读一下哦:满意的话麻烦给我分.如下代码是为了实现:接收串口过来的数据!首先初始化一个泛型类型接受容器,接收串口接口发来的数据,然后显示在界面上的edit控件上!VARIANTvariant_inp;用VARIANT泛型变量类型定义一个数组变量variant_inp;泛型就是任何类型都可以放进去的意思.作为缓冲池使用很适合.COleSafeArraysafearray_inp;用COleSafeArray用OLE安全数据容器类定义一个对象名字是safearrayinp因为VARIANT虽然可以放任何类型数据到这个数组中,但该类型没有丰富的处理成员函数,说白了他是结构体不是类,所以需要做个转换,转为COleSafeArray类型的数组类即可.他具有非常丰富的成员函数.那么,你会问为什么不直接让safearray_inp=m_ctrlm.GetInput();读缓冲区,而要经过一个中间变量呢?variant_inp=m_ctrlm.GetInput();读缓冲区safearray_inp=variant_inp;VARIANT转换成COleSafeArray型变量VARIANT和COleSafeArray是什么关系呢?原因是:这中间有调用不同的重载=运算符,m_ctrlm.GetInput();的数据可以转化为variant_inp,有默认的转化方式,而safearray_inp=variant_inp则是另一个转化方式,如果直接转,可能数据不对。VARIANT和COleSafeArray一个是结构体,一个是类,各自的数据构造不一样。longk=;初始化一个长整型变量k=;intlen;定义长度len,整数型.BYTErxdata;定义接受数据的数组,k大小,字节.为BYTE类型,也即unsignedchar类型.CStringstrtemp;定义一个CString类型的字符串strtemp;if(m_ctrlm.GetmEvent())如果控制通信对象m_ctlm有get的事件发生,{------------------------这里应该加switch(ret),将上面getmevent赋值给ret.case:事件值为表示接收缓冲区内有字符{variant_inp=m_ctrlm.GetInput();控制通信器对象得到输入数据流.如果GetmEvent返回,说明有字符到达了,接收缓冲区内有字符safearray_inp=variant_inp;将variantinp转换为COleSafeArray类型,付给safearryinp.因为COleSafeArray提供了丰富的函数处理.符合我们的需要.len=safearray_inp.GetOneDimSize();获取输入安全数组的长度lenfor(k=;k《len;k++)做个循环,{safearray_inp.GetElement(&k,rxdata+k);从输入的安全数组到rxdata进行数据拷贝.一次一个字节拷贝.}for(k=;k《len;k++)做个循环.读取len长度的所有字节.{BYTEbt=*(char*)(rxdata+k);内存rxdata起始地址+k字节偏移的指针取值,得到一个字节.strtemp.Format(“%c“,bt);strtemp赋值为bt,也就是一个字符.m_strEditRXData+=strtemp;m_strEdit这个CEdit控件显示一直加长.}}UpdateData(FALSE);将内存变量数据更新到界面.====================参考:VARIANTC++、BASIC、Java、Pascal、Script......计算机语言多种多样,而它们各自又都有自己的数据类型,产生目的,其中之一就是要跨语言(注)。而VARIANT数据类型就具有跨语言的特性,同时它可以表示(存储任意类型的数据。从C语言的角度来讲,VARIANT其实是一个结构,结构中用一个域(vt)表示------该变量到底表示的是什么类型数据,同时真正的数据则存贮在union空间中。结构的定义太长了(虽然长,但其实很简单大家去看MSDN的描述吧,这里给出如何使用的简单示例:学生:我想用VARIANT表示一个字节长的整数,如何做?老师:VARIANTv;v.vt=VT_I;v.lVal=;学生:我想用VARIANT表示布尔值“真”,如何做?老师:VARIANTv;v.vt=VT_BOOL;v.boolVal=VARIANT_TRUE;学生:这么麻烦?我能不能v.boolVal=true;这样写?老师:不可以!因为类型字节长度假值真值bool(char)(false)(true)BOOL(int)(FALSE)(TRUE)VT_BOOL(shortint)(VARIANT_FALSE)-(VARIANT_TRUE)所以如果你v.boolVal=true这样赋值,那么将来if(VARIANT_TRUE==v.boolVal)的时候会出问题(-!=)。但是你注意观察,任何布尔类型的“假”都是,因此作为一个好习惯,在做布尔判断的时候,不要和“真值”相比较,而要与“假值”做比较。学生:谢谢老师,你太牛了。我对老师的敬仰如滔滔江水,连绵不绝......学生:我想用VARIANT保存字符串,如何做?老师:VARIANTv;v.vt=VT_BSTR;v.bstrVal=SysAllocString(L“Hello,你好“);学生:哦......我明白了。可是这么操作真够麻烦的,有没有简单一些的方法?老师:有呀,你可以使用现成的包装类omVariant、COleVariant、_variant_t。比如上面三个问题就可以这样书写:omVariantv(),v(true),v(“Hello,你好“);简单了吧?!(注)学生:老师,我再问最后一个问题,我如何用VARIANT保存一个数组?老师:这个问题很复杂,我现在不能告诉你,我现在告诉你怕你印象不深......(注)学生:~!#$%^&*()......晕!VARIANT数据类型在文件OAIDL.IDL中定义如下:structtagVARIANT{union{struct__tagVARIANT{VARTYPEvt;WORDwReserved;WORDwReserved;WORDwReserved;union{ULONGLONGullVal;LONGLONGllVal;LONGlVal;BYTEbVal;SHORTiVal;FLOATfltVal;DOUBLEdblVal;VARIANT_BOOLboolVal;_VARIANT_BOOLbool;SCODEscode;CYcyVal;DATEdate;BSTRbstrVal;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;PVOIDbyref;CHARcVal;USHORTuiVal;ULONGulVal;INTintVal;UINTuintVal;DECIMAL*pdecVal;CHAR*pcVal;USHORT*puiVal;ULONG*pulVal;ULONGLONG*pullVal;INT*pintVal;UINT*puintVal;struct__tagBRECORD{PVOIDpvRecord;IRecordInfo*pRecInfo;}__VARIANT_NAME_;}__VARIANT_NAME_;}__VARIANT_NAME_;DECIMALdecVal;}__VARIANT_NAME_;};

  ⒁怎么使用COleSafeArray实现二维数组将字符串写入excel

  ⒂如何使用COleSafeArray实现二维数组将字符串写入excel//VARTYPEvt=VT_BSTR;/*数组元素的类型,string*/VARTYPEvt=VT_I;/*数组元素的类型,long*/ SAFEARRAYBOUNDsabWrite;/*用于定义数组的维数和下标的起始值*/ sabWrite.cElements=; sabWrite.lLbound=; sabWrite.cElements=; sabWrite.lLbound=; COleSafeArrayolesaWrite; olesaWrite.Create(vt,sizeof(sabWrite)/sizeof(SAFEARRAYBOUND),sabWrite); /*通过指向数组的指针来对二维数组的元素进行间接赋值*/ long(*pArray)=NULL; olesaWrite.AessData((void**)&pArray); memset(pArray,,sabWrite.cElements*sabWrite.cElements*sizeof(long)); /*释放指向数组的指针*/ olesaWrite.UnaessData(); pArray=NULL; /*对二维数组的元素进行逐个赋值*/ longindex={,}; longlFirstLBound=; longlFirstUBound=; longlSecondLBound=; longlSecondUBound=; olesaWrite.GetLBound(,&lFirstLBound); olesaWrite.GetUBound(,&lFirstUBound); olesaWrite.GetLBound(,&lSecondLBound); olesaWrite.GetUBound(,&lSecondUBound); for(longi=lFirstLBound;i《=lFirstUBound;i++) { index=i; for(longj=lSecondLBound;j《=lSecondUBound;j++) { index=j; longlElement=str[j]; //CStringlElement=ch; olesaWrite.PutElement(index,&lElement);} } /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/ VARIANTvarWrite=(VARIANT)olesaWrite; range.put_Value(varWrite); 这样能将输入的整形写入excel,当变成VT_BSTR报内存不足,求指导如何修改------解决方案--------------------可以通过另外一种写法,CRangewrite_range=start_range.get_Offset(COleVariant((long)),COleVariant((long)j));write_range.put_Value((COleVariant)(str[j]));

  ⒃关于C++VARIANT和COleSafeArray关系的一个问题

  ⒄这中间有调用不同的重载=运算符,m_ctrlm.GetInput();的数据可以转化为variant_inp,有默认的转化方式,而safearray_inp=variant_inp则是另一个转化方式,如果直接转,可能数据不对,当然,我不知道你那个m_ctrlm的类型,你可以自己试试直接等号会不会报错。VARIANT和COleSafeArray一个是结构体,一个是类,各自的数据构造不一样。只是有对应的数据转化的方式。建议你多到CSDN去,获取查询微软MSDN库以及论坛等,百度没多少高手回答的。

  ⒅COleSafeArray在串口通信中要怎么使用

  ⒆#defineDIM#defineLENvoidCTestDlg::OnTest(){BYTEivTest[LEN]=;SAFEARRAYBOUNDsab[DIM];sab.cElements=LEN;sab.lLbound=;SAFEARRAY*psa=NULL;psa=SafeArrayCreate(VT_UI,DIM,sab);for(longi=;i《LEN;i++){SafeArrayPutElement(psa,&i,&(ivTest[i]));}VARIANTvt;vt.vt=VT_ARRAY|VT_UI;vt.parray=psa;COleSafeArraysa;sa=vt;DWORDdwLen=sa.GetOneDimSize();CStringstr;str.Format(“%d“,dwLen);MessageBox(str);}---------------------------------------------------------------------------------我写了这样的一个测试程序,感觉问题应该处在你的“第一步”,也就是说,你未必完全正确的从串口缓冲区获得了有效的VARIANT数据。

您可能感兴趣的文章:

相关文章