这是第一问题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