初级代码游戏的专栏介绍与文章目录-CSDN博客
我们知道C语言的void*表示无类型的指针,或者说,void*可以接受任何指针,这简直就是个魔法。
这个魔法意味着你可以做任何事,也意味着BUG。
我今天花了一些时间来解决一个BUG。本来一切都很顺利,我早已经完成了验证代码,测试通过,我只需要把测试代码移植一下,添加一点包装就可以了。
代码主要用到了read和write函数(这太基本了啊),然而却发现读写数据不正确,但是读写的字节数是正确的,输出读写内容也是正确的,传到对方却全错了。
测试代码大致是这样的:
char ch;int i = 0;while (++i<10){ret = read(fd, &ch, 1);//注意这里是&chif (ret < 1){printf("read fail, ret is %d\r\n", ret);}else{printf("recv a char:[0x%02x][%c]\r\n", ch, ch);ret = write(fd, &ch, 1);//注意这里是&chprintf("write [%c] , ret is %d!\r\n", ch, ret);}}
这就是个串口回吐程序,读一个字节吐回一个字节,重点是串口初始化部分,跟现在说的问题无关,没有贴出来。
修改后的程序当然不能这么简单,所以就改造了一下:
bool Send(char const* data, int len){。。。。。int n = write(fd, &data, len);//注意这里是&dataif (n < 0){thelog << "串口写入失败 " << errno << " : " << strerror(errno) << ende;return false;}。。。。。。}bool Recv(char* buf, int len, long* recvLen, int timeout_ms){*recvLen = 0;。。。。。int n = read(fd, &buf + *recvLen, len - *recvLen);//注意这里是&bufif (n > 0){*recvLen += n;}。。。。。。}
然后传输的数据就是一堆乱码啊……跟踪了半天终于想起来,会不会是指针错了啊?
仔细一看果然,原来read/write的参数来自char,所以参数是&ch,新改的代码参数换成了char *,我还是保留了&啊,这就变成了char **,而这两个参数要求的是void*,所以完全合法啊,编译器当然不会有任何表示,但是世纪传入的值却错了。
为什么要允许用void*做参数类型啊?
(这里是结束)