我有一个结构:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct FieldIndex {
public fixed byte Meta[16];
}
第一个字节是TypeCode
。剩下的15个字节是UTF8编码的字符串。
我正在使用以下内容填充nameBuf
字节数组:
private static string GetMetaName (FieldIndex meta) {
var idx = 0;
var bytesOut = 1;
var nameBuf = new byte[Indexer.MAXFIELDNAMELENGTH]; // 15
while (bytesOut < Indexer.MAXFIELDLENGTH) { // 16
nameBuf[idx] = *(byte*)((byte*)&meta + bytesOut);
++bytesOut;
++idx;
}
//var src = (byte*)&field.meta + 1;
//fixed (byte* b = nameBuf) {
// *((byte*)b) = (byte)src;
//}
return BinaryConverter.ToString(nameBuf, 0, Indexer.MAXFIELDNAMELENGTH, Indexer.DefaultEncoding);
}
在上面的注释代码中,我试图在没有while
迭代的情况下完成相同的任务,但它不起作用(没有编译错误,只是错误的插值)。我可以在没有nameBuf
- 循环的情况下分配while
吗?
更新
我也更喜欢使用(byte*)
而不是Marshal.Copy
。
答案 0 :(得分:1)
您可以尝试在unsafe
上下文中使用Marshal.Copy
静态方法:
unsafe
{
Marshal.Copy(new IntPtr(meta), nameBuf, 1, nameBuf.Length);
}
答案 1 :(得分:1)
当你可以通过这种方式轻松地做到这一点时,没有太多的意义:
[StructLayout(LayoutKind.Sequential)]
struct FieldIndex {
public byte Typecode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
private byte[] Utf8string;
public string GetString() {
return Encoding.UTF8.GetString(Utf8string, 0, 15);
}
}
没有while循环,任务完成了。那个指针仍然存在并且效率很高,你只是不再看到了它。如果您经常过度调用GetString()方法,那么只需声明另一个公共类并将其保留在内部。