【发布时间】:2016-03-07 10:22:29
【问题描述】:
我有一个第三方库提供的托管数组。数组的类型并不直接反映数组中存储的数据,而是解释为整数的数据。
所以int[] data = Lib.GetData(); 给了我一个整数数组,我想将它转换成一个DataStructure 的数组,它可能看起来像这样。
struct DataStructure {
public int Id;
public double Value;
}
目前我使用Marshal.Copy(可以看到一个实现here),但是复制整个东西似乎有点过分。
这样的事情是否存在:
int[] data = Lib.GetData();
DataStructure[] dataStructs = InterpretAs<DataStructure>(data);
不需要复制,但可以像dataStruct[1].Id 一样访问dataStruct 元素?
编辑 2:
如果我只想要一个DataStructure,我可以使用
public static T ToStruct<T>(byte[] bytes) where T : struct
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T something = Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
handle.Free();
return something;
}
无需复制。
编辑:
可能重复的答案目前大约有 7 年的历史,它们包括复制数据或实施黑客攻击。
【问题讨论】:
-
这样的构造即使在 C 中也是 UB(其中原始副本也取决于实现)。您可以想象在具有强大类型系统的托管世界中......
-
@kasperhj 你确定它会导致性能问题吗?你真的需要make it faster吗?也许您可以要求第三方从他们的方法中提供更强类型的数据?在最坏的情况下,您可以尝试
unsafe代码(它应该允许这样做),但在这样做之前您应该考虑两次。 -
“我的应用程序没有性能问题,...” - 然后不要解决你没有的问题。在对 GetData() 进行看似简单的调用之后,转换可能只是杯水车薪。
-
@kasperhj Marshal.PtrToStructure
和 不需要复制的地方。 False... Marshal.PtrToStructure 对结构进行复制。该结构可以是“blittable”(因此 1:1 副本就足够了)或者可能需要一些编组(转换)。