using System; using System.Runtime.InteropServices; using System.Text; using TBL.CSharp.Base; namespace TBL.CSharp.Game.Server.Utilities; /// /// 字节块 /// public readonly unsafe struct ByteBlock { /// /// 空字节块 /// public static readonly ByteBlock Empty = new ByteBlock((void*) 0, 0); /// /// 地址 /// public readonly void* Address; /// /// 字节尺寸 /// public readonly int Size; public ByteBlock(void* ptr, int size) { Address = ptr; Size = size; } /// /// 是否在空指针 /// public bool IsNullPtr => (void*) 0 == Address; /// /// 释放 /// 不要重复进行释放操作 /// public void Free() { Marshal.FreeHGlobal(new IntPtr(Address)); } /// /// 分配所需尺寸的字节块 /// public static ByteBlock Alloc(int size) => new ByteBlock(Marshal.AllocHGlobal(size).ToPointer(), size); /// /// 分配所需尺寸的字节块并复制指定内容 /// public static ByteBlock AllocWithCopy(void* source, int size) { var block = Alloc(size); Buffer.MemoryCopy(source, block.Address, size, size); return block; } /// /// 分配装载一个非托管值的字节块 /// public static ByteBlock AllocWithValue(T value) where T : unmanaged { var block = Alloc(sizeof(T)); *(T*) block.Address = value; return block; } /// /// 分配装载一个字符串的字节块 /// public static ByteBlock AllocWithString(string str) { fixed(void* ptr = str) { return AllocWithCopy(ptr, Encoding.Default.GetByteCount(str)); } } /// /// 分配所需尺寸的字节块并初始化内容 /// public static ByteBlock AllocWithInitialize(int size, Extension.OnBufferUse initializer) { var block = Alloc(size); initializer(block.Address); return block; } }