• 通过P/Invoke控制继电器


    关于P/Invoke不用多说,主要用途就是通过托管程序(比如C#)调用非托管程序(比如C++),这个技术主要用在通过C#控制硬件等操作。主要注意点就是要看C++函数原型以及参数说明,将C++参数类型转换为对应的C#参数类型,所以要求熟悉基本的C++程序。

    这里提供一个通过C#控制电磁继电器的程序片段,以供参考。

    功能截图:

    打开时,继电器上的小灯会亮起来;关闭时,继电器上的小灯会灭掉。

    代码片段:

    namespace 电磁继电器2
    {
        public partial class Form1 : Form
        {
            private IntPtr intPtr;
            private usb_relay_device_info device;
            private int deviceNum;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct usb_relay_device_info
            {
                [MarshalAs(UnmanagedType.LPStr)]
                public string serial_number;
                [MarshalAs(UnmanagedType.LPStr)]
                public string device_path;
                public usb_relay_device_type type;
                public IntPtr next;
            }
    
            public enum usb_relay_device_type
            {
                USB_RELAY_DEVICE_ONE_CHANNEL = 1,
                USB_RELAY_DEVICE_TWO_CHANNEL = 2,
                USB_RELAY_DEVICE_FOUR_CHANNEL = 4,
                USB_RELAY_DEVICE_EIGHT_CHANNEL = 8
            }
    
            [DllImport("usb_relay_device.dll")]
            public static extern int usb_relay_init();//函数初始化
    
            [DllImport("usb_relay_device.dll")]
            public static extern IntPtr usb_relay_device_enumerate();//查找插入到电脑中的所有USB免驱继电器模块
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_device_open(IntPtr intPtr);//打开你需要操作的设备
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_device_open_with_serial_number(string serialNum, int length);//打开指定序列号的设备
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_device_open_one_relay_channel(int device, int index);//可以打开某路继电器
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_device_close_one_relay_channel(int device, int index);//可以关闭某路继电器
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_device_open_all_relay_channel(int deviceNum);//可以打开所有继电器
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_device_close_all_relay_channel(int deviceNum);//可以关闭所有继电器
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern void usb_relay_device_free_enumerate(IntPtr intPtr);// 释放内存
    
            [DllImport("usb_relay_device.dll", CallingConvention = CallingConvention.Cdecl)]
            public static extern int usb_relay_exit();//释放内存
    
            private void button1_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_init();//返回0 表示初始化ok
                intPtr = usb_relay_device_enumerate();
                object obj = Marshal.PtrToStructure(intPtr, typeof(usb_relay_device_info));
                device = ((usb_relay_device_info)obj);
                this.comboBox1.Items.Add(device.serial_number);
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                //两种方式均可打开设备
    
                //1.根据指针句柄打开设备
                //deviceNum = usb_relay_device_open(intPtr); 
    
                //2. 根据设备序列号打开设备
                deviceNum = usb_relay_device_open_with_serial_number(device.serial_number, device.serial_number.Length);
    
                this.pictureBox1.BackColor = Color.Green;
            }
    
            //1 开
            private void button3_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_device_open_one_relay_channel(deviceNum, 1);
            }
    
            //1 关
            private void button4_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_device_close_one_relay_channel(deviceNum, 1);
            }
    
            //2 开
            private void button6_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_device_open_one_relay_channel(deviceNum, 2);
            }
    
            //2 关
            private void button5_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_device_close_one_relay_channel(deviceNum, 2);
            }
    
            private void button7_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_device_open_all_relay_channel(deviceNum);
            }
    
            private void button8_Click(object sender, EventArgs e)
            {
                int flag = usb_relay_device_close_all_relay_channel(deviceNum);
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                usb_relay_device_free_enumerate(intPtr);
                int flag = usb_relay_exit();
            }
        }
    }
  • 相关阅读:
    Dom4j使用Xpath语法读取xml节点
    XML新手入门 创建构造良好的XML(2)
    XML新手入门 创建构造良好的XML(1)
    详解Java解析XML的四种方法
    Java中加载配置文件的集中方式,以及利用ClassLoader加载文件 .
    javaSE读取Properties文件的六种方法
    select
    socket
    socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto
    grep 多模式匹配
  • 原文地址:https://www.cnblogs.com/guwei4037/p/12441118.html
Copyright © 2020-2023  润新知