1. 程式人生 > >未託管資源-平臺呼叫(P/Invoke)

未託管資源-平臺呼叫(P/Invoke)




所謂非託管資源是你通過P/Invoke之類方法得到的os資源,CLR沒有辦法幫你釋放這些資源。如果你對這些資源提供了包裝WrapSource。那麼這個WrapSource是託管資源了.他可能管理了非託管資源。但他自己是託管的。



#中的API就是Win32API,即平臺呼叫(P/Invoke),一種呼叫非託管的DLL中函式的.net特性。
Windows API 是作為 Windows 作業系統一部分的動態連結庫 (DLL)。當難以自己編寫等效的過程時,可以使用它們來執行任務。在程式碼中使用 Windows API 的好處在於它們可以節省開發時間,因為它們包含許多已經編寫好的、等待使用的有用函式。缺點是在發生故障時,Windows API 可能難以處理並且不可挽回。
Windows API 表示一種特殊類別的互操作性。Windows API 不使用託管程式碼,不具備內建型別庫,它使用的資料型別與 Visual Studio 中所用的資料型別不同。由於這些差別,且 Windows API 不是 COM 物件,所以與 Windows API 和 .NET Framework 的互操作是通過使用平臺呼叫 (PInvoke) 來完成的。平臺呼叫是一種服務,它使託管程式碼能夠呼叫 DLL 中實現的非託管函式。
為了從託管程式碼中呼叫非託管的DLL中函式,你要建立一個P/Invoke包裝(Wrapper)。一個P/Invoke包裝是一個.net兼 容的方法宣告,用來建立P/Invoke包裝的語法與建立託管方法的宣告語法本質上是一樣的。唯一不同是P/Invoke包裝不包含函式體,而只有方法 名、返回值型別和引數資訊。並且,P/Invoke包裝使用了DllImport屬性。這個屬性是用來定位包含有目標函式的非託管的DLL。
例如:
MessageBox在win32的標頭檔案中的宣告:
int WINAPI MessageBoxA(HWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
那麼我們要在C#中呼叫這個MessageBox時要這樣宣告:
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll")]
public static extern int MessageBox(int hWnd, String text,
String caption, uint type);
}
然後可以用常規的.net方法去呼叫這個MessageBox:
public class HelloWorld {
public static void Main() {
Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);
}
}