這是第一問題using c# pointersC#指針VS的IntPtr
所以在c#指針是「不安全」的和而一個IntPtr是被管理對象不會被垃圾收集器管理的第二部分。但爲什麼使用指針呢?什麼時候可以交換使用兩種方法?
這是第一問題using c# pointersC#指針VS的IntPtr
所以在c#指針是「不安全」的和而一個IntPtr是被管理對象不會被垃圾收集器管理的第二部分。但爲什麼使用指針呢?什麼時候可以交換使用兩種方法?
CLI區分託管指針和非託管指針。託管指針是鍵入的,指向值的類型由運行時知道,並且只允許類型安全分配。非託管指針只能用支持它們的語言直接使用,C++/CLI就是最好的例子。
C#語言中非託管指針的等效值爲IntPtr
。您可以自由地轉換指針與來自演員。即使它的名字聽起來像「指向int的指針」,它也沒有與它關聯,它相當於C/C++中的void*
。使用這種指針需要pinvoke,Marshal類或轉換爲託管指針類型。
一些代碼一起玩:
using System;
using System.Runtime.InteropServices;
unsafe class Program {
static void Main(string[] args) {
int variable = 42;
int* p = &variable;
Console.WriteLine(*p);
IntPtr raw = (IntPtr)p;
Marshal.WriteInt32(raw, 666);
p = (int*)raw;
Console.WriteLine(*p);
Console.ReadLine();
}
}
注意unsafe
關鍵字是如何適用於本案。你可以打電話給Marshal.WriteInt64(),你什麼都不會投訴。它破壞了堆棧幀。
IntPtr
是一個託管對象,但它指向的對象仍然沒有垃圾收集。在C#中使用不安全的指針確實是你應該避免的。使用不安全指針的代碼可能不會考慮x86和x64系統之間的內存地址差異。它允許您直接操作內存地址,這與IntPtr不一樣,因爲您需要在指針和存儲在此內存地址處的實際結構之間進行編組。使用不安全的指針可以直接使用底層的類型:這裏是我寫的一個blog post,說明了不安全指針的一種可能用法。另一個常見的例子是manipulating image pixels直接。
IntPtr
不能用作指針的替代品。
IntPtr
只包含一個數值,因此您不能使用它來訪問任何數據。由此得名;它是一個與指針大小相同的整數值。您需要將該值轉換爲訪問指向的數據的指針,因此如果不使用不安全的代碼,則無法訪問數據。
另外請注意IntPtr
是一個結構,而不是一個對象,所以垃圾收集器根本就沒有直接關心它。
實際上有使用編組 – 2010-11-30 23:40:05
@Ali Tarhini:這只是調用一種爲您使用不安全代碼的方法。關鍵是最終必須使用不安全的代碼,否則無法訪問數據。 – Guffa 2010-11-30 23:42:12
解引用指向的數據由IntPtr的是這僅僅粘附的IntPtr的數量爲不安全的ptr的地址,如下
記住`IntPtr`僅僅是在.NET原始數據類型這是旨在舉行一個地址。它基本上只是一個「int」,它是32位機器上的32位和64位機器上的64位。 「IntPtr」本身沒有關於指針的具體內容。 – 2010-11-30 23:28:18