您当前的位置:首页 > 养生 > 内容

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

本文目录

  • 高分求解串口返回的VARIANT与COleSafeArray的出现在致命错误!
  • 关于串口通信中COleSafearray的问题,怎么解决
  • 关于串口通信中COleSafearray的问题
  • 单片机里I2C温度传感器采集的温度如何传到上位机上位机怎么处理数据
  • 急!龚建伟关于串口通信的程序有问题的,期望高手解决!
  • 解释一下这段程序
  • 怎么使用COleSafeArray实现二维数组将字符串写入excel
  • 关于C++ VARIANT和COleSafeArray 关系的一个问题
  • COleSafeArray在串口通信中要怎么使用

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

同时学习中。用ColeSafeArray经常会出现错误,我也没解决。我想问下,你是想操作字符串还是什么?如果是字符串可以用VARIANT的另外一个变量。VARIANT data;data=m_mscom.Getinput();CSring string;string=data.bstrval;m_show+=string+“\r\n“;UpdateData(FALSE);//在文本框中显示数据。要是二进制数据的话,不出现00字符,上面是行的。

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

其实前面已经问过了,不过不能问题补充,所以再发一次答到的,其实加起来就是120+70分了,大家帮帮忙啊在编一个串口通信程序,因为刚上手,所以是按着龚建伟书的第一章改写的。在处理接收数据的函数中void CSerTestDlg::OnComm(){VARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata;CString strtemp;if(m_ctrlComm.GetCommEvent()==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++){char bt=*(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=70在下面的程序中safearray_inp.GetElement(&k,rxdata+k)还是要报错。也就是说凡是涉及safearray_inp的都会出错。我想请教一下为什么,望不吝赐教ps:我试用了下面这种方法,但还是死在Safearray上void CSerTestDlg::OnComm(){COleVariant varInput;COleSafeArray safearray_inp;LONG lLen = 0;LONG i = 0;BYTE rxdata; //设置BYTE数组 An 8-bIT integerthat is not signed.//注意:设置接收数据if(2 == m_ctrlComm.GetCommEvent()) //事件值为2表示接收缓冲区内有字符{varInput.Attach(m_ctrlComm.GetInput()); //读缓冲区safearray_inp = varInput; //VARIANT型变量转换为ColeSafeArray型变量lLen = safearray_inp.GetOneDimSize(); //得到有效数据长度for(i = 0; i 《 lLen; i++){safearray_inp.GetElement(&i, rxdata+i); //转换为 BYTE型数组}m_strEditRXData += (char *)rxdata;UpdateData(FALSE); //更新编辑框内容}

关于串口通信中COleSafearray的问题

#define DIM 1#define LEN 9void CTestDlg::OnTest() { BYTE i1vTest[LEN] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; SAFEARRAYBOUND sab[DIM]; sab.cElements = LEN; sab.lLbound = 0; SAFEARRAY* psa = NULL; psa = SafeArrayCreate(VT_UI1, DIM, sab); for(long i = 0; i 《 LEN; i++){ SafeArrayPutElement(psa, &i, &(i1vTest[i])); } VARIANT vt; vt.vt = VT_ARRAY|VT_UI1; vt.parray = psa; COleSafeArray sa; sa = vt; DWORD dwLen = sa.GetOneDimSize(); CString str; str.Format(“%d“, dwLen); MessageBox(str);}---------------------------------------------------------------------------------我写了这样的一个测试程序,感觉问题应该处在你的“第一步”,也就是说,你未必完全正确的从串口缓冲区获得了有效的VARIANT数据。

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

1、利用串口通讯将单片机采集的温度数据传给上位机,譬如上位机可以用VC++开发2、上位机在串口接收数据事件中,可参考如下代码:void CSCommTestDlg::OnComm() {// TODO: Add your control notification handler code hereVARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata; //设置BYTE数组 An 8-bit integerthat is not signed.CString strtemp;if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符{variant_inp=m_ctrlComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize(); //得到有效数据长度for(k=0;k《len;k++)safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组for(k=0;k《len;k++) //将数组转换为Cstring型变量{BYTE bt=*(char*)(rxdata+k); //字符型strtemp.Format(“%d“,bt); //将字符送入临时变量strtemp存放m_strRXData=strtemp; //加入接收编辑框对应字符串 }}UpdateData(FALSE); //更新编辑框内容}

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

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

解释一下这段程序

小弟只有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; 定义接受数据的数组,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;  };

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

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

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

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

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

#define DIM 1#define LEN 9void CTestDlg::OnTest() { BYTE i1vTest[LEN] = ; SAFEARRAYBOUND sab[DIM]; sab.cElements = LEN; sab.lLbound = 0; SAFEARRAY* psa = NULL; psa = SafeArrayCreate(VT_UI1, DIM, sab); for(long i = 0; i 《 LEN; i++){ SafeArrayPutElement(psa, &i, &(i1vTest[i])); } VARIANT vt; vt.vt = VT_ARRAY|VT_UI1; vt.parray = psa; COleSafeArray sa; sa = vt; DWORD dwLen = sa.GetOneDimSize(); CString str; str.Format(“%d“, dwLen); MessageBox(str);}---------------------------------------------------------------------------------我写了这样的一个测试程序,感觉问题应该处在你的“第一步”,也就是说,你未必完全正确的从串口缓冲区获得了有效的VARIANT数据。


声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,谢谢。

上一篇: postcard(postcard)

下一篇: jspservlet(jsp跟servlet的区别和相同点)



推荐阅读

网站内容来自网络,如有侵权请联系我们,立即删除! | 软文发布 | 粤ICP备2021106084号