我有以下.NET值类型:
[StructLayout(LayoutKind.Sequential)]
public struct Date
{
public UInt16 V;
}
[StructLayout(LayoutKind.Sequential)]
public struct StringPair
{
public String A;
public String B;
public String C;
public Date D;
public double V;
}
Run Code Online (Sandbox Code Playgroud)
我有代码将指向值类型的指针传递给非托管代码,以及通过调用System.Runtime.InteropServices.Marshal.OffsetOf发现的偏移量.非托管代码填充Date和double值.
为StringPair结构报告的偏移量正是我所期望的:0,8,16,24,32
我在测试函数中有以下代码:
FieldInfo[] fields = typeof(StringPair).GetFields(BindingFlags.Instance|BindingFlags.Public);
for ( int i = 0; i < fields.Length; i++ )
{
int offset = System.Runtime.InteropServices.Marshal.OffsetOf(typeof(StringPair), fields[i].Name).ToInt32();
Console.WriteLine(String.Format(" >> field {0} @ offset {1}", fields[i].Name, offset));
}
Run Code Online (Sandbox Code Playgroud)
这打印出这些偏移.
>> field A @ offset 0
>> field B @ offset 8
>> field …Run Code Online (Sandbox Code Playgroud) 我一直在尝试确定在C#中使用fixed语句对于包含固定数组的托管不安全结构的真正成本.请注意我不是指非托管结构.
具体来说,有没有理由避免下面的'MultipleFixed'类显示的模式?简单地修复数据的成本是非零,接近零(==成本类似于在进入/退出固定范围时设置和清除单个标志),还是足够重要以避免在可能的情况下?
显然,这些课程是为了帮助解释这个问题而设计的.这是针对XNA游戏中的高使用率数据结构,其中此数据的读/写性能至关重要,因此如果我需要修复数组并将其传递到任何地方,我会这样做,但如果没有任何差别我我更喜欢将fixed()本地保留在方法中,以帮助保持函数签名对于不支持不安全代码的平台更加轻松.(是的,它的一些额外的咕噜声代码,但不管它需要......)
unsafe struct ByteArray
{
public fixed byte Data[1024];
}
class MultipleFixed
{
unsafe void SetValue(ref ByteArray bytes, int index, byte value)
{
fixed(byte* data = bytes.Data)
{
data[index] = value;
}
}
unsafe bool Validate(ref ByteArray bytes, int index, byte expectedValue)
{
fixed(byte* data = bytes.Data)
{
return data[index] == expectedValue;
}
}
void Test(ref ByteArray bytes)
{
SetValue(ref bytes, 0, 1);
Validate(ref bytes, 0, 1);
}
}
class SingleFixed
{
unsafe void SetValue(byte* data, int index, …