讓拖管代碼對象和非託管對象協同工做的過程稱爲互用性(Interoperability),一般簡稱爲 Interop。
P/Invoke在託管代碼與非託管代碼交互式時產生一個事務(Transition),這一般發生在使用平臺調用服務(Platfrom Invocation Services)即P/Invoke。容許託管代碼調用平臺(Platfrom)相關的非託管代碼(c++、VB、Delphi....)
Com Interop 一種服務,它使 .NET Framework 對象可以與 COM 對象通訊。
如調用系統的 API 或與 COM 對象打交道,經過 System.Runtime.InteropServices 命名空間
雖然使用 Interop 很是方便,但據估計每次調用事務都要執行 10 到 40 條指令,算起來開銷也很多,因此咱們要儘可能少調用事務
若是非用不可,建議本着一次調用執行多個動做,而不是屢次調用每次只執行少許動做的原則c++
The frequency of the sound, in hertz. This parameter must be in the range 37 through 32,767 (0x25 through 0x7FFF).c#
If the function succeeds, the return value is nonzero.windows
If the function fails, the return value is zero. To get extended error information, call api
RequirementsDLL Kernel32.dll網絡
[DllImportAttribute("kernel32.dll")] public static extern bool Beep([In]uint dwFreq, [In] uint dwDuration);
CLR會找到kernel32.dll使用loadlibrary函數加載起來,而後經過GetProcAddress函數查找到Beep入口點地址,而後就能夠經過入口點地址調用Beep函數。在調用以前CLR會作一些狀態切換,須要進行參數轉換.NET的32int 轉換爲 c++的32整型(在這裏因爲.NET的int 和c++的32整形是同樣的因此不用轉換能夠直接傳遞)。可是也有複雜的狀況,在字符串的狀況下CRl須要把字符串內容備份拷貝,轉換編碼以\0結尾的字符串內存傳遞給c++。app
函數入口點 函數
缺省爲託管函數的名字 工具
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.InteropServices; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace demo1 9 { 10 11 12 [StructLayoutAttribute(LayoutKind.Sequential)] 13 public struct HWND__ 14 { 15 16 /// int 17 public int unused; 18 } 19 20 public partial class NativeMethods 21 { 22 23 /// Return Type: int 24 ///hWnd: HWND->HWND__* 25 ///lpText: LPCSTR->CHAR* 26 ///lpCaption: LPCSTR->CHAR* 27 ///uType: UINT->unsigned int 28 [DllImportAttribute("user32.dll", EntryPoint = "MessageBoxA")] 29 public static extern int MessageBoxA([InAttribute()] System.IntPtr hWnd, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPStr)] string lpText, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPStr)] string lpCaption, uint uType); 30 31 } 32 class Program 33 { 34 /// <summary> 35 /// 用於生成簡單的聲音 36 /// </summary> 37 /// <param name="dwFreq"> Long,聲音頻率(從37Hz到32767Hz)。在windows95中忽略</param> 38 /// <param name="dwDuration"> Long,聲音的持續時間,以毫秒爲單位。如爲-1,表示一直播放聲音,直到再次調用該函數爲止。在windows95中會被忽略</param> 39 /// <returns>Long,TRUE(非零)表示成功,不然返回零。會設置GetLastError</returns> 40 [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, EntryPoint = "Beep", ExactSpelling = true, SetLastError = true)] 41 public static extern bool Beep([In]int dwFreq, [In] int dwDuration); 42 43 [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "MessageBox")] 44 public static extern bool MsgBox(IntPtr hwnd,string text, string caption ,int type); 45 46 47 static void Main(string[] args) 48 { 49 NativeMethods.MessageBoxA(IntPtr.Zero, "123", "321", 0); 50 // Marshal.GetLastWin32Error(); 51 MsgBox(IntPtr.Zero, "123", "321",2); 52 53 int[] ss = new int[7] { 262, 294, 330, 349, 392, 440, 494 }; 54 55 for (int i = 1; i < 8; i++) 56 { 57 Beep(ss[i-1] / 2, 500); 58 Console.WriteLine("低" + i); 59 Beep(0, 1000); 60 61 62 } 63 for (int i = 1; i < 8; i++) 64 { 65 Beep(ss[i - 1] , 500); 66 Console.WriteLine("中" + i); 67 Beep(0, 1000); 68 } 69 for (int i = 1; i < 8; i++) 70 { 71 Beep(ss[i - 1] * 2, 500); 72 Console.WriteLine("高" + i); 73 Beep(0, 1000); 74 } 75 76 77 //C#自帶的應該也是經過上面的手段調用winapi 78 int x = 9; 79 // 80 if ( 81 ((x >= 1) && (x <= 9))) 82 { 83 for (int i = 1; i <= x; i++) 84 { 85 Console.WriteLine("Beep number {0}.", i); 86 Console.Beep(1111, 1111); 87 } 88 } 89 else 90 Console.WriteLine("Usage: Enter the number of times (between 1 and 9) to beep."); 91 92 } 93 94 } 95 }
本文爲學習筆記 若有侵犯請聯繫我 ,學習課程名 由張羿主講的《公共語言運行庫(CLR)開發系列課程(1):Pinvoke簡介》 百度能夠搜索到相關學習資料 我收集資料並不全官方不提供下載了 如今只有視頻提供下載 第三方地址 學習