colesafearray谁能帮我解释一下这段程序的意思?最好每一句特别是开头那几句有什么作用?万分感谢
colesafearray 时间:2021-07-11 阅读:(
)
如何使用数组参数
如果一个函数以一维数组为参数,我们可以这样声明这个函数
void func(int* a) ;
void func(int a[]) ;
void func(int a[3]) ;
实际上,这三种形式是等价的,在使用数组做参数时,编译器会自动将数组名转换为指向数组第一个元素的指针,为什么呢?这要从参数的传递方式说起,参数有三种传递方式,按值传递,按指针传递,按引用传递,分别如下
void Test(int a) ;
void Test(int* a) ;
void Test(int& a) ;
第一种方式传递的是a的一个副本
第二种方式传递的是指向a的指针的一个副本
第三种方式传递的是指向a的引用的一个副本
既然都是副本,那么就存在拷贝到过程,但是,数组是不能直接拷贝的,也就是不能像下面这样
int a[3] = {1, 2, 3} ;
int b[](a) ; // error
int b[3] ;
b = a ; // error
不能用一个数组初始化另一个数组,也不能将一个数组直接赋值给另外一个数组,如果想复制数组,唯一的办法就是逐个元素复制。
int a[3] = {1, 2, 3} ;
int b[3] ;
for (int i = 0; i < 3; ++i)
{
b[i] = a[i] ;
}
既然数组不能拷贝,那么参数该如何传递呢?于是编译器就将数组名转换成了指向第一个元素的指针,指针是可以拷贝的。
但是这也引发了另外一个问题。
我们无法只通过数组名得知数组元素的个数。
看下面的代码
void Test(int a[3])
{
for (int i = 0; i < 5; ++i)
{
cout << a[i] << endl ;
}
}
明明只传递了三个元素的数组,为什么输出5个元素?前面已经说了,数组被转换成了指向第一个元素的指针,所以上面的代码和下面的相同
void Test(int* a) //我只知道a是个指针,跟本不知道a指向多少个元素
{
for (int i = 0; i < 5; ++i)
{
cout << a[i] << endl ;
}
}
编译器根本不知奥数组a有多少个元素,它甚至不知道a是数组!如何解决呢,一种办法是再加一个参数,指定元素个数
void Test(int* a, int n)
{
for (int i = 0; i < n; ++i)
{
cout << a[i] << endl ;
}
}
另外一种办法是传递数组的引用,这才是本文的重点,唉,前面这么多废话:(
void Test(int (&a)[3])
{
for (int i = 0; i < 3; ++i)
{
cout << a[i] << endl ;
}
}
这样写数组a就不会被转换为指针了,而且有了元素个数的信息,调用的时候,也必须传递一个含有3个元素的数组
int a[3] = {1, 2, 3} ;
Test(a) ; // ok
int b[1] = {1} ;
Test(b) ; // error, can not convert parameter a from int[1] to int(&)[3]
And that’s all, Happy coding!
==The End==vc中COleVarian是什么意思
整体意思是将VARIANT中的数据以ASCII码保存至 rxdata字节数组,再存入m_strEditRXData字符串变量中,VARIANT是结构,没有成员函数,无法直接转换,只能先赋值给COleSafeArray,然都将数据一个字节一个字节赋值给 rxdata,再将bt转化成strtemp字...VC++中通过mscomm控件,用什么函数读取返回到串口的信息
这是我写的接收函数,你看看
OnOnCommCommctrl()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
//设置接收BYTE数组
BYTE rxdata[2048];
CString strtemp;
if(bReceive)
{
//事件值是2,表示接收缓冲区内有字符
if(m_Com.GetCommEvent()==2)
{
//读缓冲区
variant_inp=m_Com.GetInput();
//转换数值类型
safearray_inp=variant_inp;
//得到有效数据长度
len=safearray_inp.GetOneDimSize();
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE 型数组
for(k=0;k<len;k++)
{
BYTE bt=*(char*)(rxdata+k); //字符型
if(m_nOutPutMode == 2)
strtemp.Format("%02X ",bt); //将字符以十六进制方式送入临时变量strtemp存放,注意这里加入一个空隔
else
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
// Receive2 = Receive2 + strtemp; //加入接收编辑框对应字符串
}
}
}
//更新编辑框内容
UpdateData(FALSE);
}关于串口通信中COleSafearray的问题,怎么解决
其实前面已经问过了,不过不能问题补充,所以再发一次
答到的,其实加起来就是120+70分了,大家帮帮忙啊
在编一个串口通信程序,因为刚上手,所以是按着龚建伟书的第一章改写的。
在处理接收数据的函数中
void CSerTestDlg::OnComm()
{
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048];
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[2048]; //设置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); //更新编辑框内容
}vc串口setportout怎么用
操作方法
1.建立项目:打开VC,建立一个基于对话框的MFC应用程序SCommTest;
2.在项目中插入MSComm控件
选择Project菜单下Add To Project子菜单中的 Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。
选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到 们的Project中来,接受缺省的选项。
(如果 在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是 在安装VC6时没有把ActiveX一项选上,重新安装VC6,选上ActiveX就可以了),
这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。
3.利用ClassWizard定义CMSComm类控制对象
打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时 可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #include "m.h" //}}AFX_INCLUDES 。
4.在对话框中添加控件 向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。
别忘记了将接收编辑框的Properties->Styles中把Miltiline和Vertical Scroll属性选上,发送编辑框若 想输入多行文字,也可选上Miltiline。
再打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类, 为IDC_EDIT_RXDATA添加CString变量m_strRXData, 为IDC_EDIT_TXDATA添加CString变量m_strTXData。
说明: m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。
5.添加串口事件消息处理函数OnComm()
打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm。
这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件, 们刚才添加的函数就会执行, 们在OnComm()函数加入相应的处理代码就能实现自已想要的功能了。
请 在函数中加入如下代码:
void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置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
safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
for(k=0;k
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
m_strRXData+=strtemp; //加入接收编辑框对应字符串
}
}
UpdateData(FALSE); //更新编辑框内容
}
到目前为止还不能在接收编辑框中看到数据,因为 们还没有打开串口,但运行程序不应该有任何错误,不然, 肯定哪儿没看仔细,因为 是打开VC6对照着做一步写一行的,运行试试。
没错吧?那么做下一步:
6.打开串口和设置串口参数
可以在 需要的时候打开串口,例如在程序中做一个开始按钮,在该按钮的处理函数中打开串口。
现在 们在主对话框的CSCommTestDlg::OnInitDialog()打开串口,加入如下代码:
// TODO: Add extra initialization here
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);
m_ctrlComm.SetCommPort(1); //选1
if( !m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port");
m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位
m_ctrlComm.SetInputModel(1); //1:表示以二进制方式检取数据
m_ctrlComm.SetRThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
现在 可以试试程序了,将串口线接好后(不会接?去看看 写的串口接线基本方法),打开串口调试助手,并将串口设2,选上自动发送,也可以等会手动发送。
再执行 编写的程序,接收框里应该有数据显示了。
7.发送数据
先为发送按钮添加一个单击消息即BN_CLICKED处理函数,打开ClassWizard->Message Maps,选择类CSCommTestDlg,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED添加OnButtonManualsend()函数,并在函数中添加如下代码:
void CSCommTestDlg::OnButtonManualsend()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //读取编辑框内容
m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据
}
运行程序,在发送编辑框中随意输入点什么,单击发送按钮,啊!看看,在另一端的串口调试助手(或别的调试工具)接收框里出现了什么。
说明:
由于用到VC控件,在没有安装VC的计算机上运行时要从VC中把m32.ocx、msvcrt.dll、mfc42.dll拷到Windows目录下的System子目录中(win2000为System32)并再进行注册设置。
谁能帮我解释一下这段程序的意思?最好每一句特别是开头那几句有什么作用?万分感谢
小弟只有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) , 将上面mevent赋值给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(); 获取输入安全数组的长度len
for(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;
};
Megalayer 商家我们还算是比较熟悉的,商家主要业务方向是CN2优化带宽、国际BGP和全向带宽的独立服务器和站群服务器,且后来也有增加云服务器(VPS主机)业务。这次中秋节促销活动期间,有发布促销活动,这次活动力度认为还是比较大的,有提供香港、美国、菲律宾的年付VPS主机,CN2优化方案线路的低至年付159元。这次活动截止到10月30日,如果我们有需要的话可以选择。第一、特价限量年付VPS主...
酷番云怎么样?酷番云就不讲太多了,介绍过很多次,老牌商家完事,最近有不少小伙伴,一直问我台湾VPS,比较难找好的商家,台湾VPS本来就比较少,也介绍了不少商家,线路都不是很好,有些需求支持Windows是比较少的,这里我们就给大家测评下 酷番云的台湾VPS,支持多个版本Linux和Windows操作系统,提供了CN2线路,并且还是原生IP,更惊喜的是提供的是无限流量。有需求的可以试试。可以看到回程...
totyun,新公司,主要运作香港vps、日本vps业务,接入cn2网络,不限制流量!VPS基于KVM虚拟,采用系统盘和数据盘分离,从4G内存开始支持Windows系统...大家注意下,网络分“Premium China”、“Global”,由于站长尚未测试,所以也还不清楚情况,有喜欢吃螃蟹的尝试过不妨告诉下站长。官方网站:https://totyun.com一次性5折优惠码:X4QTYVNB3P...
colesafearray为你推荐
scanf_sscanf_s和以前的scanf是一样等级的吗???settimermfc里SetTimer和Sleep有什么区别李昊天李昊天这名字给多少分slideshare如何通过slideshare扩充LinkedIn人脉jdk6我是win7的系统,安装了JDK6,环境配置都正确了。但是安装完没有应用程序啊~索引超出了数组界限求助大神什么叫索引超出了数组界限系统论坛怎么进论坛12306注册12306怎么注册账号水表读数普通家庭一天水表读数是多少银联商务招聘银联商务加钞员是正式员工吗
enom cpanel php主机 512av shopex空间 ssh帐号 ibox官网 php空间申请 我爱水煮鱼 阿里云浏览器 有奖调查 服务器维护方案 512mb 湖南idc 谷歌台湾 apnic 上海联通 globalsign 时间同步服务器 paypal登陆 更多