在C#中从IntPtr访问元素感到困惑[关闭]

问题描述 投票:3回答:1

我正在使用Kinect v2,其中包含以下CameraSpacePoint结构:

public struct CameraSpacePoint : IEquatable<CameraSpacePoint>
{
    public float X;
    public float Y;
    public float Z;
}

CameraSpacePoint也包含很少的方法EqualsGetHashCode等,上面没有显示,以保持帖子干净和短。

好吧,我在类构造函数中定义cameraSpacePoints如下:

IntPtr cameraSpacePoints = Marshal.AllocHGlobal(512 * 424 * 4 * 3);

以下是对上述内存分配的解释:

  • 512:宽度
  • 424:身高
  • 4:单个'float'所需的字节数
  • 3:总共三个变量,即'X','Y'和'Z'

后来,我使用CoordinateMapper将值复制到cameraSpacePoints,如下所示:

coordinateMapper.MapDepthFrameToCameraSpaceUsingIntPtr(depthFrameData,
                                                   512 * 424 * 2,
                                                   cameraSpacePoints,
                                                   512 * 424 * 4 * 3);

看起来很完美。现在我想从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从cameraSapacePoints访问元素时会有一些混乱。这里缺少什么?有什么建议吗?

c# kinect
1个回答
2
投票

在您的初始代码中,您将IntPtr(指向CameraSpacePoint的数组[])转换为原始浮点指针。如果你将IntPtr解释为原始floats,因为你一次处理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中,那么针对新版本重新编译代码将再次起作用,而直接访问floats会破坏封装并使维护变得困难。

我们不再需要将循环增加3的原因是因为当我们在cameraSpacePoints[index]上使用下标/索引操作时,编译器知道在初始n * sizeof(CameraSpacePoint)的位置之后在cameraSpacePoints[0]的偏移处找到元素n。而sizeof(CameraSpacePoint)的大小为3个花车。

© www.soinside.com 2019 - 2024. All rights reserved.