问题描述
尝试从C#中的C ++读取结构时遇到问题.我做了多次,并且始终有效,但是我从未使用过浮点数.
I have a problem when trying to read a struct from C++ in C#.I did this more times and it worked always, but i never used floating point numbers.
这些是我在C#端使用的结构:
These are the structs i use on the C# side:
[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 ++方面使用的结构:
This are the structs i use on the C++ side:
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#部分获取数据:
Now the C# part which has been used to get the data:
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 ++):
And finally the part which is used to retrieve data( 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#中读取时,杂项编号是正确的,并且控制台会告诉我正确的编号,但是所有浮点数都已损坏,并且在C ++和C#中获得不同的编号时.无论如何,差异是可以接受的. (在C ++中为340,在C#中为0.xxxxxxx左右).
The misc number is correct when reading it in C# and the Console tells me the correct numbers, but all floats are corrupted and when i get different numbers in C++ and C#. Anyway the difference is to large to accept it. ( Got 340 in C++ and around 0.xxxxxxx in C# ).
任何帮助都将受到欢迎.谢谢.
Any help would be welcome. Thanks.
推荐答案
是因为.Net Boolean
的大小与C ++实现bool
的大小不同吗?我认为VC ++对bool
使用1个字节,而.Net对System.Boolean
使用2个或4个字节.
Could it be because the .Net Boolean
is not the same size as your C++ implementation bool
? I think VC++ uses 1 byte for bool
while .Net uses 2 or 4 bytes for System.Boolean
.
尝试将IsValid定义为Byte
而不是Boolean
,然后查看它是否有效.
Try defining IsValid as Byte
instead of Boolean
and see if it works.
我认为您还可以在Boolean
之前添加MarshalAs属性,以强制将其封送为1字节:
I think you can also add the MarshalAs attribute before Boolean
to force it to be marshaled as 1-byte:
[StructLayout(LayoutKind.Sequential)]
public struct UserData
{
public UInt32 misc;
[MarshalAs(UnmanagedType.U1)]
public Boolean IsValid;
public VirtualPosition RightHand;
public VirtualPosition LeftHand;
public VirtualPosition Head;
}
但是我不确定它是否适合您的情况,因为您直接使用指针而不是封送处理.
But I'm not sure it's going to work in your case, since you directly use pointers, not marshaling.
这篇关于C ++/C#浮点问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!