關於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(); } } }