unity常用代码Native
参考 c#指针IntPtr
参考 c#调用c++
主要用到的类有
-
Allocator
内存分配枚举值,说明要分配什么样的内存
Invalid
无效分配。
None
未分配,当使用NativeArrayUnsafeUtility用非托管内存指针创建 NativeArray 时可以传入 None ,让 NativeArray 直接使用传入的内存
Temp
最快的分配方法,适用于一帧内的生命时长,不能将该类型分配的数据传给 Job,用完调用Dispose
比如在一个同步函数的开始分配内存,在函数结束前调用 DisposeTempJob 分配速度比 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个作用- 调用 AtomicSafetyHandle.Release , 把 AtomicSafetyHandle 置成已释放状态
- 在析构函数中检查是否处于释放状态,否则提示内存泄漏
-
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种处理方式-
使用变量的地方在定义变量时添加 [NativeDisableUnsafePtrRestriction] 属性
-
自己设置 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); -
使用临时的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

最低0.47元/天 解锁文章
9958

被折叠的 条评论
为什么被折叠?



