C#中的IntPtr類型(指針等用)


(213條消息) C#中的IntPtr類型(指針等用)_u011555996的博客-CSDN博客_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類型的變量,這樣會使程序變得難於理解並容易出錯。

希望這些信息對您有幫助。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
本文章已收錄於:
 
  • 近來研究指針,在C#中談指針,就不得不談IntPtr,以下是我對IntPtr的初步了解,一些基礎。

 

一:什么是IntPtr

先來看看MSDN上說的:用於表示指針或句柄的平台特定類型。這個其實說出了這樣兩個事實,IntPtr 可以用來表示指針或句柄、它是一個平台特定類型。對於它的解釋,這個哥們寫的比較好:It's a class that wraps a pointer that is used when calling Windows API functions. The underlying pointer may be 32 bit or 64 bit, depending on the platform.

二:用在什么地方

(1)C#調用WIN32 API時

(2)C#調用C/C++寫的DLL時(其實和1相同,只是這個一般是我們在和他人合作開發時經常用到)

三:怎樣用

例如有一函數原型定義為:DLLDemo_API int __stdcall Inptr_Test (LONG param1, HWND hWnd);那么我們在C#中引用時就要這樣寫:

 [DllImport("DllPlayer.dll", EntryPoint = "IP_TPS_OpenStream")]
 public static extern int  Inptr_Test (int param1, IntPtr hWnd);

在調用的時候就可以向Inptr_Test 的第二個參數傳入某一控件的Handle。這里涉及到C#類型與C++類型的對應關系,網上這種有很多,這里就不再贅述,只談幾個經常用到的和經常出錯的。

      (1)一般對於char* ,void*這種可以直接對應IntPtr,比如在C#中,我們經常用string類型,其轉換為IntPtr再傳給char*,void*等,轉換方法為

string txt="test"; Marshal.StringToCoTaskMemAuto(txt);

這里有時會用StringToCoTaskMemAnsi,不過StringToCoTaskMemAuto自動分配內存就可以了。這樣就會將txt的內容復制到非托管的內存塊中。

(2)對於結構體,比如有一結構體 StructText,將其轉換為Intptr,盡量不要直接用Marshal.StructureToPtr,這樣很容易出錯。可以這樣來用:

int
size = Marshal.SizeOf(StructText);//獲取結構體占用空間大小

IntPtr
intptr= Marshal.AllocHGlobal(size);//聲明一個同樣大小的空間

 

Marshal.StructureToPtr(StructText, intptr, true);//將結構體放到這個空間中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM