C# 指针操作

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

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值