C# 指针操作

mac2026-05-26  2

以下总结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);

 

最新回复(0)