搜索
bottom↓
回复: 14

C# out 传返回值,提示类型未经处理的异常

[复制链接]

出0入8汤圆

发表于 2019-9-3 15:07:48 | 显示全部楼层 |阅读模式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace parse
{
    public class SerialParse
    {

        //串口接收结构体
        public struct dsRxCtrl
        {
            public uint rxCnt;
            public uint rxLen;
            public byte rxState;
            public byte[] buf;
        }

        //构造函数
        public SerialParse()
        {
            m_rxCtrl.buf = new byte[1000];
            m_rxCtrl.rxCnt = 0;
            m_rxCtrl.rxLen = 0;
            m_rxCtrl.rxState = 0;
        }

        //串口接收
        public dsRxCtrl m_rxCtrl;

        public byte get_xor(byte[] data, int len)
        {
            byte check = 0;

            if (len == 0) return 0;

            check = data[0];

            for (int i = 1; i < len; i++)
            {
                check ^= data[i];
            }

            return check;
        }

        //串口接收解析
        //head (1 byte)  cmd (1 byte)  fun(1 byte) len(1byte) data ( n  byte ) check (1 byte, xor) tail ( 1 byte )
        public bool parse_recv(byte temp, out byte[] byteArray)
        {

            bool ret = false;
         
            byteArray = new byte[1000];

            if (m_rxCtrl.rxCnt < 200)
            {
                m_rxCtrl.buf[m_rxCtrl.rxCnt++] = temp;
            }

            switch (m_rxCtrl.rxState)
            {
                case 0:
                    if (temp == 0xa5)
                    {
                        m_rxCtrl.rxState = 1;
                        m_rxCtrl.rxCnt = 1;
                        m_rxCtrl.buf[0] = temp;
                    }
                    else
                    {
                        m_rxCtrl.rxCnt = 0;
                        m_rxCtrl.rxLen = 0;
                        m_rxCtrl.rxState = 0;
                    }
                    break;
                case 1://head
                    if (temp == 0xa5)
                    {
                        m_rxCtrl.rxState = 1;
                        m_rxCtrl.rxCnt = 1;
                        m_rxCtrl.buf[0] = temp;
                    }
                    else
                    {
                        m_rxCtrl.rxState = 2;//cmd
                    }
                    break;

                case 2:
                    m_rxCtrl.rxState = 3;//fun
                    break;


                case 3://len
                    m_rxCtrl.rxLen = temp;
                    m_rxCtrl.rxState = 4;
                    break;

                case 4:
                    if (m_rxCtrl.rxCnt >= (m_rxCtrl.rxLen + 6))
                    {
                        if (m_rxCtrl.buf[m_rxCtrl.rxLen + 6 - 1] == 0x0d)
                        {

                            int len = (int)(m_rxCtrl.rxLen) + 4;
                            byte check = get_xor(m_rxCtrl.buf, len);

                            if (check != m_rxCtrl.buf[m_rxCtrl.rxLen + 6 - 2])
                            {
                                Console.WriteLine("check err");
                            }
                            else
                            {
                              
                                byteArray = new byte[m_rxCtrl.rxLen + 6];

                                for( int i = 0; i< m_rxCtrl.rxLen+6; i++ )
                                {
                                    byteArray[i] = m_rxCtrl.buf[i];
                                }
                                ret = true;
                            }
                        }
                        else
                        {
                            Console.WriteLine("recv err frame ?");
                        }

                        m_rxCtrl.rxCnt = 0;
                        m_rxCtrl.rxLen = 0;
                        m_rxCtrl.rxState = 0;
                    }
                    break;

                default:
                    break;

            }//end switch

   

            return ret;

        }//end fun
    }//end class
}

写了一个解析类,

从c转过来的代码,通过状态机解析串口数据是否符合协议,如果是,就通过out将完整的数据帧传出去,让上层处理。

才学两天,对out ref理解可能不是很到位。 没有c里面指针那种方式,有点适应不过来。

串口协议格式:

//head (1 byte)  cmd (1 byte)  fun(1 byte) len(1byte) data ( N  byte ) check (1 byte, xor) tail ( 1 byte )

实际有效长度由len字段决定,属于不定长数据接收。

大家给点意见。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2019-9-3 17:58:38 | 显示全部楼层
没看你程序,不知道你为什么要用out,你直接 return byte[] data 不就好了

出0入8汤圆

 楼主| 发表于 2019-9-3 19:45:53 | 显示全部楼层
7073640 发表于 2019-9-3 17:58
没看你程序,不知道你为什么要用out,你直接 return byte[] data 不就好了

这个只能传出一组啊, 比如要out几组数呢

出0入0汤圆

发表于 2019-9-3 20:05:31 | 显示全部楼层
list<byte[]>  要多少有多少

出0入0汤圆

发表于 2019-9-3 20:39:00 | 显示全部楼层
justdomyself 发表于 2019-9-3 19:45
这个只能传出一组啊, 比如要out几组数呢

tuple 类型了解一下  

出0入8汤圆

 楼主| 发表于 2019-9-3 23:49:36 | 显示全部楼层
7073640 发表于 2019-9-3 20:05
list  要多少有多少

多维度的数组呢,多类型多维度的数据呢

出0入0汤圆

发表于 2019-9-4 00:22:45 | 显示全部楼层
自己封装一个类返回也行呀

出0入8汤圆

 楼主| 发表于 2019-9-4 08:44:09 | 显示全部楼层
浮生莫若闲 发表于 2019-9-4 00:22
自己封装一个类返回也行呀

类也可以拿来返回啊

其实我最想返回的是结构体指针

出0入0汤圆

发表于 2019-9-4 08:49:11 | 显示全部楼层
justdomyself 发表于 2019-9-3 23:49
多维度的数组呢,多类型多维度的数据呢

为什么你就这么无视我的 tuple  ?

出0入36汤圆

发表于 2019-9-4 08:58:04 | 显示全部楼层
本帖最后由 norman33 于 2019-9-4 09:00 编辑

out参数要在调用外面就实例化好,而且进入out的函数后变量会自动清空,楼主的数组在函数里面实例化当然会报错
改成:
        public byte[] byteArray = new byte[1000];
        public bool parse_recv(byte temp, out byte[] byteArray)
        {

            bool ret = false;
         
            //直接使用byteArray变量

C#有更方便的List<byte>,楼主可以了解下

出0入8汤圆

 楼主| 发表于 2019-9-4 09:10:40 | 显示全部楼层
norman33 发表于 2019-9-4 08:58
out参数要在调用外面就实例化好,而且进入out的函数后变量会自动清空,楼主的数组在函数里面实例化当然会报 ...

首先谢谢你。

外部定义的byte数组是他自己的固定的长度。

内部返回的串口帧是不定长的。

如何让外部知道返回的不定长的串口帧的长度。

出0入0汤圆

发表于 2019-9-4 09:12:52 | 显示全部楼层
接楼上,可以用C# 7.0的新特性,调用含out函数。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入36汤圆

发表于 2019-9-4 09:26:45 | 显示全部楼层
justdomyself 发表于 2019-9-4 09:10
首先谢谢你。

外部定义的byte数组是他自己的固定的长度。


你可以用byte[]静态数组来做缓冲的话,只能接收函数里定义一个长度变量 比如 int length = 0;
然后在接收到的地方自己计算长度然后跟着数组一起返回,由于有长度变量了,你原来那个返回的bool可以直接用int来返回长度,长度为0就是false,不为0就是true
我建议你还是用List<byte>来作为返回参数,这样静态数组也不要了,函数来直接用add或者addrange来填充数据,返回后只要查看返回的List<byte>的count就能知道长度。
public List<byte> parse_recv(byte temp)
{
        List<byte> ret = new List<byte>();
        ......
        //依次填入数据
        //ret.add(i);
        //填入一组数据
        //ret.AddRange(a);
        //a可以是数组或者List<byte>变量
}

调用:
List<byte> getData = parse_recv(temp);
获取长度:getData.count;
读取数据可以按你熟悉的下标来读getData[0] 等;

出0入0汤圆

发表于 2019-9-4 13:07:52 | 显示全部楼层
justdomyself 发表于 2019-9-4 09:10
首先谢谢你。

外部定义的byte数组是他自己的固定的长度。

这是C#啊,不是C啊,改变思想,这么多方法可以用,也可以用委托,把函数在你接收函数里面处理数据

出0入8汤圆

 楼主| 发表于 2019-9-5 11:17:46 | 显示全部楼层
norman33 发表于 2019-9-4 09:26
你可以用byte[]静态数组来做缓冲的话,只能接收函数里定义一个长度变量 比如 int length = 0;
然后在接收 ...

照你说的弄了个,运行起来感觉比out 传数组慢一些
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 10:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表