尝试在C#中从C ++读取结构时遇到问题。 我做了这么多次,它总是有效,但我从来没有使用过浮点数。
这些是我在C#端使用的结构:
[StructLayout(LayoutKind.Sequential)]
public struct ImageData
{
public UInt32 Width;
public UInt32 Height;
public UInt32 Length;
public IntPtr PixelPointer;
}
[StructLayout(LayoutKind.Sequential)]
public struct UserData
{
public UInt32 misc;
public Boolean IsValid;
public VirtualPosition RightHand;
public VirtualPosition LeftHand;
public VirtualPosition Head;
}
[StructLayout(LayoutKind.Sequential)]
public struct VirtualPosition
{
public Position3D RealPosition;
public Position3D ProjectedPosition;
}
[StructLayout(LayoutKind.Sequential)]
public struct Position3D
{
public float X;
public float Y;
public float Z;
}
这是我在C ++方面使用的结构:
typedef struct XnVector3D
{
XnFloat X;
XnFloat Y;
XnFloat Z;
} XnVector3D;
class VirtualPosition {
public:
XnVector3D RealPosition;
XnVector3D ProjectedPosition;
VirtualPosition(void) { }
VirtualPosition(XnVector3D real, XnVector3D projected) {
RealPosition = real;
ProjectedPosition = projected;
}
};
class UserData
{
public:
int misc; // Misc number to check if i have the correct pointer ( debug only )
bool Valid;
VirtualPosition RightHand;
VirtualPosition LeftHand;
VirtualPosition Head;
};
现在用于获取数据的C#部分:
public unsafe UserData GetUserData(UInt32 user)
{
IntPtr pos = GetData(_Index, user);
UserData* ptr = ((UserData*)pos.ToPointer());
UserData result = *ptr;
return result;
}
[DllImport("KinectNative.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetData(Int32 index, UInt32 user);
最后用于检索数据的部分(C ++):
EXPORT UserData* GetData(int index, XnUserID user)
{
if (_LastData != NULL) _LastData->~UserData();
system("cls");
_LastData = new UserData(_Context->GetDevice(index)->GetData(user));
std::cout << "X: " << (int)_LastData->Head.ProjectedPosition.X << " Y:" << (int)_LastData->Head.ProjectedPosition.Y << std::endl;
return _LastData;
}
在C#中读取时,misc编号是正确的,并且控制台告诉我正确的数字,但所有浮动都已损坏,当我在C ++和C#中获得不同的数字时。无论如何,差异是大到接受它。 (在C ++中得到340,在C#中得到约0.xxxxxxx)。
欢迎任何帮助。感谢。
答案 0 :(得分:3)
可能是因为.Net Boolean
与C ++实现bool
的大小不同吗?我认为VC ++使用1个字节用于bool
,而.Net使用2个或4个字节用于System.Boolean
。
尝试将IsValid定义为Byte
而不是Boolean
,看看它是否有效。
我认为您还可以在Boolean
之前添加MarshalAs属性,以强制将其封送为1个字节:
[StructLayout(LayoutKind.Sequential)]
public struct UserData
{
public UInt32 misc;
[MarshalAs(UnmanagedType.U1)]
public Boolean IsValid;
public VirtualPosition RightHand;
public VirtualPosition LeftHand;
public VirtualPosition Head;
}
但是我不确定它会在你的情况下起作用,因为你直接使用指针,而不是编组。
答案 1 :(得分:0)
在CLI中,bool定义为4字节,但sizeof会将其报告为1字节。所有0代表False,其他任何东西都被认为是真的。