2017年9月25日 星期一

C#中的IntPtr類型

https://read01.com/zh-tw/DAOJK.html#.WcjooMgjFPY

C#中的IntPtr類型

問:
c#中無法將類型「int」隱式轉換為「System.IntPtr」
這個是我引用了一個api函數時出現的問題,我在聲明中把intptr換成了int還是不可以,這是為什麼呢?要如何處理呢?

答:
您好,C#中的IntPtr類型稱為「平台特定的整數類型」,它們用於本機資源,如窗口句柄。
資源的大小取決於使用的硬體和作業系統,但其大小總是足以包含系統的指針(因此也可以包含資源的名稱)。

所以,在您調用的API函數中一定有類似窗體句柄這樣的參數,那麼當您聲明這個函數時,您應該將它顯式地聲明為IntPtr類型。

例如,在一個C#程序中調用Win32API mciSendString函數控制光碟驅動器,這個函數的函數原型是:

MCIERROR mciSendString
(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
);

首先在C#中聲明這個函數:

[DllImport("winmm.dll")]

private static extern long mciSendString(string a,string b,uint c,IntPtr d);

然後用這樣的方法調用:

mciSendString("set cdaudio door open", null, 0, this.Handle);

您也可以使用IntPtr.Zero將句柄設置為0;

或者使用類型強制轉換:

mciSendString("set cdaudio door open", null, 0, (IntPtr)0 );

或者,使用IntPtr構造函數:

IntPtr a = new IntPtr(2121);

這裡有兩點比較重要:

一是在C#中聲明Win32API時,一定要按照WinAPI的原型來聲明,不要改變它的數據類型;

二是儘量不要過多使用類型強制轉換或構造函數的方式初始化一個IntPtr類型的變量,這樣會使程序變得難於理解並容易出錯。

希望這些信息對您有幫助。



沒有留言:

張貼留言