seb*_*ebf 5 .net c# managed marshalling
我有一些代码用于从字节数组中获取结构:
public static T GetValue<T>(byte[] data, int start) where T : struct
{
T d = default(T);
int elementsize = Marshal.SizeOf(typeof(T));
GCHandle sh = GCHandle.Alloc(d, GCHandleType.Pinned);
Marshal.Copy(data, start, sh.AddrOfPinnedObject(), elementsize);
sh.Free();
return d;
}
Run Code Online (Sandbox Code Playgroud)
但是,结构d永远不会被修改,并始终返回其默认值.
我已经查找了"正确"的方法,并且正在使用它,但仍然很好奇,因为我不明白为什么上面的内容不起作用.
它可以很简单:分配一些内存,d,获取指向它的指针,将一些字节复制到由此指向的内存中,返回.不仅如此,但是当我使用类似的代码但是d是T的数组时,它工作正常.
除非sh.AddrOfPinnedObject()没有真正指向d,但那有什么意义呢?
谁能告诉我为什么以上不起作用?
Han*_*ant 10
GCHandle sh = GCHandle.Alloc(d, GCHandleType.Pinned);
Run Code Online (Sandbox Code Playgroud)
这就是你的问题开始的地方.struct是一种值类型,GCHandle.Alloc()只能为引用类型分配句柄.在垃圾收集堆上分配对象的类型.而那种使钉扎变得明智的东西.C#编译器在这里有点太有用了,它会自动发出一个装箱转换来装箱值并使语句有效.这通常非常好,并且产生了从System.Object派生值类型的错觉.嘎嘎叫鸭子打字.
问题是,Marshal.Copy()将更新值的盒装副本. 不是你的变量.所以你没有看到它改变.
只有Marshal.PtrToStructure()才能直接更新结构值.它包含将结构的已发布布局(StructLayout属性)转换为内部布局所需的智能.这是不一样的,否则是不可发现的.
| 归档时间: |
|
| 查看次数: |
2964 次 |
| 最近记录: |