困惑从IntPtr的访问元素在C#
我使用的Kinect V2包含以下CameraSpacePoint结构:困惑从IntPtr的访问元素在C#
public struct CameraSpacePoint : IEquatable<CameraSpacePoint> {
public float X;
public float Y;
public float Z;
}
的CameraSpacePoint
还包含一些方法Equals
,GetHashCode
等,上面没有显示保留职位干净而短暂。
好,我在类构造定义cameraSpacePoints
如下:
IntPtr cameraSpacePoints = Marshal.AllocHGlobal(512 * 424 * 4 * 3);
下面是上述存储器分配的说明:
- 512:宽度
- 424:高度
- 4 :单个“浮点数”所需的字节数
- 3:总共三个变量,即'X','Y
coordinateMapper.MapDepthFrameToCameraSpaceUsingIntPtr(depthFrameData,
512 * 424 * 2,
cameraSpacePoints,
512 * 424 * 4 * 3);
似乎完美的:'和 'Z'
后来,我用CoordinateMapper如下复制值cameraSpacePoints。现在我想从cameraSpacePoints获取值。所以我用下面的代码里面unsafe
块:
float* cameraSpacePoint = (float*)cameraSpacePoints; for (var index = 0; index < 512 * 424; index++)
{
float X = cameraSpacePoint[index];
float Y = cameraSpacePoint[index + 1];
float Z = cameraSpacePoint[index + 2];
}
它似乎没有我,而它的可视化实现的工作。在我看来,使用IntPtr
从cameraSaPointPoints访问元素时存在一些混淆。这里缺少什么?有什么建议吗?
回答:
在您的初始代码中,您正在将IntPtr
(指向CameraSpacePoint
的数组[]]指向原始浮点型指针。如果您将IntPtr
解释为原始的float
s,由于您一次处理3个点(x,y和z),因此您需要每次将循环增加3个浮点数。 (我已经改名为清楚起见变量):
var floats = (float*)cameraSpacePoints; for (var index = 0; index < 512 * 424; index+=3)
{
var x = floats[index];
var y = floats[index + 1];
var z = floats[index + 2];
var myCameraSpacePoint = new CameraSpacePoint
{
X = x,
Y = y,
Z = z
};
// use myCameraSpacePoint here
}
但是,这是处理数据一个可怕的低效的方式,因为该数据最初在任何情况下一个CameraSpacePoint
。更好的将只是施放的结构直接返回到实际类型:
var cameraSpacePoints = (CameraSpacePoint*)cameraSpacePoints; for (var index = 0; index < 512 * 424; index++)
{
var cameraSpacePoint = cameraSpacePoints[index];
// Do something with cameraSpacePoint
}
通过转换成正确的类型(CameraSpacePoint
),我们也提高了代码的健壮性 - 例如如果未来将更多字段添加到CameraSpacePoint
的新版本中,那么针对新版本的代码重新编译将再次运行,而直接访问float
会破坏封装并使维护变得困难。
我们之所以不再需要将循环增加3,是因为当我们在cameraSpacePoints[index]
上使用下标/索引操作时,编译器是否知道在位置为n * sizeof(CameraSpacePoint)
之后发现元素n初始的cameraSpacePoints[0]
。并且sizeof(CameraSpacePoint)
是3个浮标的大小。
以上是 困惑从IntPtr的访问元素在C# 的全部内容, 来源链接: utcz.com/qa/263639.html