以下总结C#指针操作的知识点
一、unsafe的用法
1、C#使用指针首先要用unsafe声明
unsafe声明可以用在方法或代码块
(1)方法声明为unsafe
static unsafe void Main(string[] args) { int var = 20; int* p = &var; Console.WriteLine("Data is: {0} ", var); Console.WriteLine("Address is: {0}", (int)p); Console.ReadKey(); }(2)将代码块声明为unsafe
public static void Main(string[] args) { unsafe { int var = 10; int* p = &var; Console.WriteLine("var:{0}", var); //可以使用 ToString() 方法检索存储在指针变量所引用位置的数据 Console.WriteLine("var:{0}", p->ToString()); Console.WriteLine("Address:{0}", (int)p); } Console.ReadKey(); }2、使用unsafe时,首先要设置编译器,允许编译不安全代码
项目文件-属性-生成-勾选不安全代码
二、C#指针操作
1、fixed
fixed 语句可防止垃圾回收器重新定位可移动的变量。 fixed 语句仅允许存在于不安全的上下文中。 还可以使用 fixed 关键字创建固定大小的缓冲区。 fixed 语句将为托管变量设置一个指针,并在该语句的执行过程中“单边锁定”该变量。 仅可在 fixed 上下文中使用指向可移动托管变量的指针。 如果没有 fixed 上下文,垃圾回收可能会不可预测地重定位变量。 C# 编译器只允许将指针分配给 fixed 语句中的托管变量。
2、对C#的数组用指针进行操作
C#的数值是引用类型,其中C#的指针类型不允许是引用类型
const int size = 2048 * 300 * 2; int line = 300; //int d = 0; short[] genePic = new short[size]; for (int i = 0; i < size; i++) { genePic[i] = (short)i; } //取数组genePic的地址,并将其传给ptr IntPtr ptr; unsafe { void* p; fixed (short* pc = genePic) { p = (void*)pc; ptr = new IntPtr(p); } }3、C# IntPtr类型
IntPtr类型称为“平台特点的整数类型”用于表示指针或句柄的平台特定类型。
IntPtr类型设计为一个整数,其大小是特定于平台的。 也就是说,此类型的实例应该是32位硬件和操作系统上的32位,以及64位硬件和操作系统上的64位。
IntPtr类型具体用法参考如下:
https://docs.microsoft.com/zh-cn/dotnet/api/system.intptr?view=netframework-4.8
4、Marshal类
Marshal类提供了一个方法集合,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。
(1)根据指针读取指针的内容
//将指针IntPtr ptr指向的内容拷贝到数组genePic2 short[] genePic2 = new short[size]; for (int i = 0; i < size; i++) { genePic2[i] = Marshal.ReadInt16(ptr+2*i);//读取指针指向的内容 }(2)将 16 位整数值写入非托管内存
static void WriteInt16(IntPtr ptr, short val);ptr 非托管内存中要写入的地址。 Int16 要写入的值。
Marshal类具体用法参考如下:
https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.marshal?view=netframework-4.8
三、常用类型转换总结
1、C# 字符串转C char *
string s_filePath = "test.txt"; //字符串转指针 ntPtr p_filePath = Marshal.StringToCoTaskMemAnsi(s_filePath);
