C#调用C++库,进行串口通信

1、添加C++接口实现,将dll放置在运行路径下。

dll文件下载:https://files.cnblogs.com/files/ZM191018/SerialPortLib.rar?t=1722937417&download=true

     [DllImport("SerialPortLib.dll",CharSet=CharSet.Unicode,CallingConvention =CallingConvention.StdCall)]
        static extern int openDevice(string COMName, int dwBaud, string sframe, ref UIntPtr hCom);

        [DllImport("SerialPortLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        static extern int closeDevice(UIntPtr hCom);

        [DllImport("SerialPortLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        static extern int startComminication(RECEIVE_CALLBACK receive, byte[] sendData, int dlen, UIntPtr hCom);

2、调用接口打开串口设备

复制代码
      UIntPtr hCom2 = UIntPtr.Zero;
        private void button3_Click(object sender, EventArgs e)
        {
            string strComName = comboBox1.Text;
            int iBaud = Convert.ToInt32(comboBox2.Text);
            string strFrame = comboBox3.Text;
            try
            {
                int iret = openDevice(strComName, iBaud, strFrame, ref hCom2);
                if (iret == 0)
                {
                    button3.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
复制代码

3、调用接口将委托作为参数传入,当读取到数据时,进行回调

复制代码
      public delegate int RECEIVE_CALLBACK(IntPtr recvData, int dlen);
        private void button5_Click(object sender, EventArgs e)
        {
            string sendStr = richTextBox1.Text;
            byte[] sendArr=StringToHexByteArray(sendStr);

            int iret=startComminication(new RECEIVE_CALLBACK(RecvCallBack), sendArr,sendArr.Length, hCom2);
        }

        public int RecvCallBack(IntPtr recvData, int dlen)
        {
            if (recvData != null && dlen > 0)
            {
                byte[] data = new byte[dlen];
                Marshal.Copy(recvData, data, 0, dlen);
                string str = BitConverter.ToString(data, 0, (int)dlen).Replace("-", "");
                this.Invoke((EventHandler)delegate
                {
                    richTextBox2.AppendText(str + "\n");
                    richTextBox2.SelectionStart = richTextBox2.Text.Length;
                    richTextBox2.ScrollToCaret();

                });
                return 0;
            }
            else
            {
                return -1;
            }
        }
复制代码

4、关闭串口

复制代码
private void button4_Click(object sender, EventArgs e)
        {
            int iret = closeDevice(hCom2);
            if (iret == 0)
            {
                hCom2 = UIntPtr.Zero;
                button3.Enabled = true;
            }

        }
复制代码

5、可能用到的方法

复制代码
     public static byte[] StringToHexByteArray(string hex)
        {
            if (hex.Length % 2 == 1)
                return null;
            int len = hex.Length >> 1;
            byte[] arr = new byte[len];

            for (int i = 0; i < len; ++i)
            {
                arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }

            return arr;
        }

        public static int GetHexVal(char hex)
        {
            int val = (int)hex;
            //For uppercase A-F letters:
            // return val - (val < 58 ? 48 : 55);
            //For lowercase a-f letters:
            //return val - (val < 58 ? 48 : 87);
            //Or the two combined, but a bit slower:
            return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
        }
复制代码

 6、效果

 

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        

        [DllImport("SerialPortLib.dll",CharSet=CharSet.Unicode,CallingConvention =CallingConvention.StdCall)]
        static extern int openDevice(string COMName, int dwBaud, string sframe, ref UIntPtr hCom);

        [DllImport("SerialPortLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        static extern int closeDevice(UIntPtr hCom);

        [DllImport("SerialPortLib.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        static extern int startComminication(RECEIVE_CALLBACK receive, byte[] sendData, int dlen, UIntPtr hCom);


        UIntPtr hCom = UIntPtr.Zero;
        public Form1()
        {
            InitializeComponent();
            string[] ports=SerialPort.GetPortNames();
            for(int i = 0; i < ports.Length; i++)
            {
                comboBox1.Items.Add(ports[i]);
            }
            if (comboBox1.Items.Count > 0)
            {
                comboBox1.SelectedIndex = 0;
            }
            comboBox2.SelectedIndex = 0;
            comboBox3.SelectedIndex = 0;
            callBack = new RECEIVE_CALLBACK(RecvCallBack);
            callBack2 = new RECEIVE_CALLBACK(RecvCallBack2);

        }

        UIntPtr hCom2 = UIntPtr.Zero;
        private void button3_Click(object sender, EventArgs e)
        {
            string strComName = comboBox1.Text;
            int iBaud = Convert.ToInt32(comboBox2.Text);
            string strFrame = comboBox3.Text;
            try
            {
                int iret = openDevice(strComName, iBaud, strFrame, ref hCom2);
                if (iret == 0)
                {
                    button3.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            int iret = closeDevice(hCom2);
            if (iret == 0)
            {
                hCom2 = UIntPtr.Zero;
                button3.Enabled = true;
            }

        }

        public delegate int RECEIVE_CALLBACK(IntPtr recvData, int dlen);
        public RECEIVE_CALLBACK callBack;
        public RECEIVE_CALLBACK callBack2;
        Thread thr1;
        Thread thr2;
        private void button5_Click(object sender, EventArgs e)
        {
            string sendStr = string.Empty;
            this.Invoke((EventHandler)delegate
            {
                sendStr = richTextBox1.Text;

            });
            byte[] sendArr=StringToHexByteArray(sendStr);

            int iret=startComminication(callBack, sendArr,sendArr.Length, hCom2);
            if (iret != 0)
            {
                trytimes1++;
                if (trytimes1 > 3)
                {
                    flag1 = false;
                    thr1.Join();
                }
            }
        }

        public int RecvCallBack(IntPtr recvData, int dlen)
        {
            try
            {
                if (recvData != null && dlen > 0)
                {
                    byte[] data = new byte[dlen];
                    Marshal.Copy(recvData, data, 0, dlen);
                    string str = BitConverter.ToString(data, 0, (int)dlen).Replace("-", "");
                    this.Invoke((EventHandler)delegate
                    {
                        richTextBox2.AppendText(str + "\n");
                        richTextBox2.SelectionStart = richTextBox2.Text.Length;
                        richTextBox2.ScrollToCaret();

                    });
                    trytimes1 = 0;
                    return 0;
                }
                else
                {
                    trytimes1++;
                    if (trytimes1 > 3)
                    {
                        flag1 = false;
                        thr1.Join();
                    }
                    return -1;
                }
            }
            catch(Exception ex)
            {
                return -1;
            }
            
        }

        private void button6_Click(object sender, EventArgs e)
        {
            string sendStr = string.Empty;
            this.Invoke((EventHandler)delegate
            {
                sendStr = richTextBox3.Text;

            });
            byte[] sendArr = StringToHexByteArray(sendStr);

            int iret = startComminication(callBack2, sendArr, sendArr.Length, hCom);
            if (iret != 0)
            {
                trytimes2++;
                if (trytimes2 > 3)
                {
                    flag2 = false;
                    thr2.Join();
                }
            }
        }
        int trytimes2 = 0;
        int trytimes1 = 0;
        public int RecvCallBack2(IntPtr recvData, int dlen)
        {
            try
            {
                if (recvData != null && dlen > 0)
                {
                    byte[] data = new byte[dlen];
                    Marshal.Copy(recvData, data, 0, dlen);
                    string str = BitConverter.ToString(data, 0, (int)dlen).Replace("-", "");
                    this.Invoke((EventHandler)delegate
                    {
                        richTextBox4.AppendText(str + "\n");
                        richTextBox4.SelectionStart = richTextBox4.Text.Length;
                        richTextBox4.ScrollToCaret();

                    });
                    trytimes2 = 0;
                    return 0;

                }
                else
                {
                    trytimes2++;
                    if (trytimes2 > 3)
                    {
                        flag2 = false;
                        thr2.Join();
                    }
                    return -1;
                }
            }
            catch(Exception ex)
            {
                return -1;
            }
            
        }

        public static byte[] StringToHexByteArray(string hex)
        {
            if (hex.Length % 2 == 1)
                throw new Exception("The binary key cannot have an odd number of digits");

            int len = hex.Length >> 1;
            byte[] arr = new byte[len];

            for (int i = 0; i < len; ++i)
            {
                arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
            }

            return arr;
        }

        public static int GetHexVal(char hex)
        {
            int val = (int)hex;
            //For uppercase A-F letters:
            // return val - (val < 58 ? 48 : 55);
            //For lowercase a-f letters:
            //return val - (val < 58 ? 48 : 87);
            //Or the two combined, but a bit slower:
            return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string strComName = comboBox1.Text;
            int iBaud = Convert.ToInt32(comboBox2.Text);
            string strFrame = comboBox3.Text;
            try
            {
                int iret = openDevice(strComName, iBaud, strFrame, ref hCom);
                if (iret == 0)
                {
                    button2.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        

        private void button1_Click(object sender, EventArgs e)
        {
            int iret = closeDevice(hCom);
            if (iret == 0)
            {
                hCom = UIntPtr.Zero;
                button2.Enabled = true;
            }
        }

        private void richTextBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void button7_Click(object sender, EventArgs e)
        {
            thr1 = new Thread(run1);
            thr2 = new Thread(run2);
            thr1.Start();
            thr2.Start();
            button7.Enabled = false;
        }

        bool flag1 = true;
        private void run1()
        {
            flag1 = true;
            while (flag1)
            {
                Thread.Sleep(10);
                button5_Click(null, null);
                
            }
        }
        bool flag2 = true;
        private void run2()
        {
            flag2 = true;
            while (flag2)
            {
                Thread.Sleep(10);
                button6_Click(null, null);
            }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            flag1 = false;
            flag2 = false;
            button7.Enabled = true;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(MessageBox.Show("关闭窗体?","提示", MessageBoxButtons.OKCancel)==DialogResult.Cancel)
            {
                e.Cancel = true;
            }

        }
    }
}
打开多串口
复制代码

 

posted @   !>Mon<!  阅读(80)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示