【发布时间】:2015-05-13 11:11:54
【问题描述】:
GCHandle.Alloc 拒绝使用包含“decimal”数据类型的结构来确定数组,但同时可以很好地处理“double”。这是什么原因,我可以通过某种方式解决它吗?
我知道我可以改为使用 unsafe/fixed 来获取指向数组的指针,但这不适用于泛型。 :-(
演示问题的完整示例代码。第一个 Alloc 有效,但第二个失败并出现
对象包含非原始数据或非 blittable 数据。
public struct X1
{
public double X;
}
public struct X2
{
public decimal X;
}
现在试试这个:
var x1 = new[] {new X1 {X = 42}};
var handle1 = GCHandle.Alloc(x1, GCHandleType.Pinned); // Works
var x2 = new[] { new X2 { X = 42 } };
var handle2 = GCHandle.Alloc(x2, GCHandleType.Pinned); // Fails
【问题讨论】:
-
decimal与 `double. Double 是本机类型,而 decimal 是 128 位结构 -
您还可以将 double 视为 64 位结构。
-
这不是视角问题。 Double 是一种原生类型,如“操作系统和 CPU 原生支持它”。小数虽然“只是”一个内部布局使用 4 个 DWORD 的结构。 OLE 使用相同的布局(实际上就是它的来源),它允许您交换数据,例如与 VB/VBA。 C/C++ 虽然不知道如何处理它
-
当然你是对的,但在这种情况下,我对数据代表什么或布局完全不感兴趣。我只想要一个指向原始数据的指针。我可以在上面的代码中使用“fixed(void* ptr = x1”)) 来做到这一点。但我想找到一种通用的方法。就这样。结构包含的内容并不重要,只要其中没有引用即可。
-
GCHandle.Alloc甚至拒绝确定DateTime[]或int?[],仅供参考...
标签: c# .net memory-management