假设我有一个如下定义的值类型:
[StructLayout(LayoutKind.Explicit, Size=40)]
public struct Storage
{
}
这个类的唯一目的是占用40字节的内存。有没有办法轻松读取第 n 个字节?例如,我想写这个函数:
byte ReadFromStorage(ref Storage s, int n)
{
}
同样对于写入版本。我需要此函数的性能尽可能接近以下 C 代码:
return *((char*)s + n);
假设我有一个如下定义的值类型:
[StructLayout(LayoutKind.Explicit, Size=40)]
public struct Storage
{
}
这个类的唯一目的是占用40字节的内存。有没有办法轻松读取第 n 个字节?例如,我想写这个函数:
byte ReadFromStorage(ref Storage s, int n)
{
}
同样对于写入版本。我需要此函数的性能尽可能接近以下 C 代码:
return *((char*)s + n);
请改用固定大小的缓冲区。
也就是说,没有什么能阻止您在unsafe
上下文中执行以下操作(假设您使用的是显式布局):
unsafe byte ReadFromStorage(ref Storage s, int n)
{
fixed(Storage* ptr = &s)
{
return ((byte*)ptr)[n];
}
}
没有理由为此使用不安全的代码。
static byte ReadFromStorage(Storage s, int n) {
var handle = default(GCHandle);
try {
handle = GCHandle.Alloc(s, GCHandleType.Pinned);
var ptr = handle.AddrOfPinnedObject();
var arrSize = Marshal.SizeOf(typeof(Storage));
var arr = new Byte[arrSize];
Marshal.Copy(ptr, arr, 0, arrSize);
return arr[n];
} finally {
if (handle.IsAllocated)
handle.Free();
}
}
在反复进行一些修改并阅读威廉的评论之后,这只是对Marshal.ReadByte的调用,但这看起来不像杂耍处理程序和 try-finally-statements 那样酷。
var b = Marshal.ReadByte(s, n);