C ++ / C#浮动问题

时间:2011-05-05 12:23:28

标签: c# c++ interop

尝试在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)。

欢迎任何帮助。感谢。

2 个答案:

答案 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,其他任何东西都被认为是真的。