unity常用代码Native

unity常用代码Native

参考 c#指针IntPtr
参考 c#调用c++

主要用到的类有

  • Allocator
    内存分配枚举值,说明要分配什么样的内存
    Invalid
    无效分配。
    None
    未分配,当使用NativeArrayUnsafeUtility用非托管内存指针创建 NativeArray 时可以传入 None ,让 NativeArray 直接使用传入的内存
    Temp
    最快的分配方法,适用于一帧内的生命时长,不能将该类型分配的数据传给 Job,用完调用Dispose
    比如在一个同步函数的开始分配内存,在函数结束前调用 Dispose

    TempJob
    	分配速度比 Temp 慢比 Persistent 快,4帧的生命时长且线程安全。若四帧内没有调用Dispose,控制台会打印原生代码生成的警告。
    	大部分小任务都使用该类型分配NativeContainer
    	比如给一个job分配内存,等分配线程后执行完毕释放内存,必须保证在4帧内完成
    
    Persistent
    	是对malloc的包装,能够维持尽可能地生命时长,在非常注重性能的情况下不应使用 Persistent
    
  • DisposeSentinel
    这个类主要给 NativeArray 使用,用来监测内存是否正确释放,也就是检测内存泄漏
    在 NativeArray 构造时调用 DisposeSentinel.Create 创建 AtomicSafetyHandle 和 DisposeSentinel
    只有 allocator != Allocator.Temp 才会创建 DisposeSentinel
    在 NativeArray.Dispose 时调用 DisposeSentinel.Dispose 释放 AtomicSafetyHandle 和 DisposeSentinel,用于监测 NativeArray 是否被释放,有2个作用

    1. 调用 AtomicSafetyHandle.Release , 把 AtomicSafetyHandle 置成已释放状态
    2. 在析构函数中检查是否处于释放状态,否则提示内存泄漏
  • AtomicSafetyHandle
    这个类主要给 NativeArray 使用,用来保证线程安全的
    在 NativeArray 构造时调用 DisposeSentinel.Create 创建 AtomicSafetyHandle 和 DisposeSentinel
    safety = ((allocator == Allocator.Temp) ? AtomicSafetyHandle.GetTempMemoryHandle() : AtomicSafetyHandle.Create());
    在 NativeArray.Dispose 时调用 DisposeSentinel.Dispose 释放 AtomicSafetyHandle 和 DisposeSentinel
    if (!AtomicSafetyHandle.IsTempMemoryHandle(safety)) {AtomicSafetyHandle.Release(safety);}
    当我们使用 NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray 把一个指针转成 NativeArray 时,直接使用[]访问元素可能会触发AtomicSafetyHandle.CheckReadAndThrow 异常,这时候可以有2种处理方式

    1. 使用变量的地方在定义变量时添加 [NativeDisableUnsafePtrRestriction] 属性

    2. 自己设置 AtomicSafetyHandle

          NativeArray<byte> bytes = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(ptr, data.Length, Unity.Collections.Allocator.None);
          // 仅在 ENABLE_UNITY_COLLECTIONS_CHECKS 开启时才设置,不然有些平台会报错
          #if ENABLE_UNITY_COLLECTIONS_CHECKS
          // 设置 AtomicSafetyHandle
          AtomicSafetyHandle safetyHandle = AtomicSafetyHandle.Create();
          NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref bytes, safetyHandle);
          #endif
          DoSomething(bytes);
          // 释放 AtomicSafetyHandle
          AtomicSafetyHandle.Release(safetyHandle);
      
    3. 使用临时的AtomicSafetyHandle

          NativeArray<byte> bytes = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(ptr, data.Length, Unity.Collections.Allocator.None);
          // 仅在 ENABLE_UNITY_COLLECTIONS_CHECKS 开启时才设置,不然有些平台会报错
          #if ENABLE_UNITY_COLLECTIONS_CHECKS
          // 设置 AtomicSafetyHandle
          AtomicSafetyHandle safetyHandle = AtomicSafetyHandle.GetTempUnsafePtrSliceHandle();
          #endif
          NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref bytes, safetyHandle);
      
  • Unity.Collections.LowLevel.Unsafe.UnsafeUtility
    封装了很多数组拷贝,转换,托管内存和非托管内存操作等
    AddressOf 此结构的内存地址。
    AlignOf 结构的最小对齐单位,跟c++对齐类似,一个结构体只包含 char 和 int ,则对齐大小为 4+4=8
    CopyObjectAddressToPtr 分配对结构或固定类的对象引用
    CopyPtrToStructure 从 ptr 向 output 复制 sizeof(T) 个字节。
    CopyStructureToPtr 从 input 向 ptr 复制 sizeof(T) 个字节。
    EnumToInt 不需要拆箱,直接获得枚举值的整形表达式
    Free 释放内存
    GetFieldOffset 返回字段相对于结构或其所在类的偏移。
    IsBlittable 返回此结构是否可直接复制到本机结构中,此结构应只包含blittable数值类型,在跟c通信时不应声明MarshalAs
    blittable数值类型指托管代码和原生代码的二进制表达方式一致,比如 byte int float,不包括 bool string
    IsUnmanaged 返回结构或类型是否非托管的. 非托管类型不包含任何托管字段,可自由复制
    非托管类型可参考枚举值 UnmanagedType
    IsValidNativeContainerElementType 判断某种类型是否可以做为 NativeContainer 的元素
    Malloc 分配内存。
    MemClear 清除内存。
    MemCmp 通过将第一个给定内存缓冲区中的指定内存区域与第二个给定内存缓冲区中的相同区域进行比较,检查两个内存区域是否相同。
    MemCpy 复制内存,如果源和目标重叠,不保证结果正确,此时应改用 MemMove
    MemCpyReplicate 复制内存,顺序复制
    MemCpyStride 与 MemCpy 类似,但可以通过 desinationStride 和 sourceStride 跳过字节
    MemMove 移动内存。
    MemSet 用某个值填充内存
    PinGCArrayAndGetDataAddress 保持对该对象的强 GC 引用并将其固定。保证对象在移动 GC 中的内存位置不会移动。
    返回数组第一个元素的地址。另请参阅:UnsafeUtility.ReleaseGCObject。
    PinGCObjectAndGetAddress 保持对该对象的强 GC 引用并将其固定。保证对象在移动 GC 中的内存位置不会移动。
    返回该对象的内存位置地址。另请参阅:UnsafeUtility.ReleaseGCObject。
    ReleaseGCObject 释放之前由 UnsafeUtility.PinGCObjectAndGetAddress 获取的 GC 对象句柄。
    SizeOf 结构的大小。
    WriteArrayElement 写入数组元素。
    WriteArrayElementWithStride 使用步幅写入数组元素。

  • NativeArray
    代表非托管内存中的数组,内部调用 UnsafeUtility
    本身不提供获取内存指针的函数,但可以通过 NativeArrayUnsafeUtility 直接操纵内存
    IsCreated 指示 NativeArray 有一个已分配的内存缓冲区。
    Length ativeArray 中元素的数量。
    this[int] 按索引访问 NativeArray 元素。请注意,结构是按值而非引用返回的。

    NativeArray		构造函数,Allocator参考上面的说明
    CopyFrom		从长度相同的另一个 NativeArray 或托管数组中复制所有元素。
    CopyTo			将所有元素复制到长度相同的另一个 NativeArray 或托管数组。
    Dispose		
    GetEnumerator	获取枚举器。
    GetSubArray		获得指定起始位置开始的指定长度的数组,引用原来的数组中的数据块,不能主动删除
    Reinterpret		转成别的元素类型的数组,引用原数组的数据块,不能主动删除
    ReinterpretLoad	获得把某个索引处的元素并转成别的类型
    ReinterpretStore  用别的类型的值设置某个索引处的元素
    ToArray			将 NativeArray 转换为托管数组。
    
    静态函数
    Copy			将一系列元素从源数组复制到目标数组,从源索引开始将它们复制到目标索引。
    
    常用代码
    	//	分配内存空间
    	NativeArray<byte> array = new NativeArray<byte>(1000, Allocat
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值