C# 在C中从IntPtr访问元素时感到困惑#

C# 在C中从IntPtr访问元素时感到困惑#,c#,kinect,C#,Kinect,我使用的Kinect v2包含以下结构: 下面是对上述内存分配的说明: 512:宽度 424:高度 4:单个“浮点”所需的字节数 3:总共三个变量,即“X”、“Y”和“Z” 稍后,我使用以下方法将值复制到cameraSpacePoints: IntPtr cameraSpacePoints = Marshal.AllocHGlobal(512 * 424 * 4 * 3); coordinateMapper.MapDepthFrameToCameraSpaceUsingIntPtr(dep

我使用的Kinect v2包含以下结构:

下面是对上述内存分配的说明:

  • 512:宽度
  • 424:高度
  • 4:单个“浮点”所需的字节数
  • 3:总共三个变量,即“X”、“Y”和“Z”
稍后,我使用以下方法将值复制到cameraSpacePoints:

IntPtr cameraSpacePoints = Marshal.AllocHGlobal(512 * 424 * 4 * 3);
coordinateMapper.MapDepthFrameToCameraSpaceUsingIntPtr(depthFrameData,
                                                   512 * 424 * 2,
                                                   cameraSpacePoints,
                                                   512 * 424 * 4 * 3);
看起来很完美。现在我想从cameraSpacePoints获取值。因此,我在
不安全
块中使用了以下代码:

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];
}
float*cameraSpacePoint=(float*)cameraSpacePoints;
对于(var索引=0;索引<512*424;索引++)
{
浮动X=摄影机空间点[索引];
浮动Y=摄影机空间点[索引+1];
浮动Z=摄影机空间点[索引+2];
}

我在想象它时意识到它似乎不起作用。在我看来,使用
IntPtr
从cameraSapacePoints访问元素时出现了一些混乱。这里少了什么?有什么建议吗

在初始代码中,您正在将
IntPtr
(指向
CameraSpacePoint
的数组[])强制转换为原始浮点指针。如果您将
IntPtr
解释为原始
float
s,因为您一次处理3个点(x、y和z),那么每次需要将循环增加3个float,例如(为了清楚起见,我重命名了变量):

通过强制转换到正确的类型(
CameraSpacePoint
),我们也在提高代码的健壮性-例如,如果将来在新版本的
CameraSpacePoint
中添加了其他字段,那么针对新版本重新编译代码将再次起作用,而直接访问
float
s将破坏封装并使维护变得困难


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

尝试在for循环中将
index++
替换为
index+=3
——似乎一次要做3个浮点数。另外,作为对单个浮点*进行强制转换的替代方法,您可以强制转换到
CameraSpacePoint
,它将封装X、Y和Z。@StuartLC:情况变得更好了,现在我看到了三个相同数据的副本。换句话说,我在同一扇窗户里看到了自己三次!LOL@StuartLC:令人惊讶的是,施法技巧奏效了<代码>CameraSpacePoint*CameraSpacePoint=(CameraSpacePoint*)cameraSpacePoints
然后
X=cameraSpacePoint[index].X,
你能回答并解释一下为什么
float*
不起作用,但“cameraSpacePoint*`起作用吗?非常感谢。@StuartLC:另外,我把
index+=3
改回
index++
。因为现在每个
索引都是
CameraSpacePoint
。你还建议我使用
index+=3
?我已经将我的评论汇总成一个答案-希望这能澄清问题。
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];
}
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
}
var cameraSpacePoints = (CameraSpacePoint*)cameraSpacePoints;
for (var index = 0; index < 512 * 424; index++)
{
    var cameraSpacePoint = cameraSpacePoints[index];
    // Do something with cameraSpacePoint
}