关于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(); } } }