【发布时间】:2018-02-27 00:16:42
【问题描述】:
我在一个嵌入式 MCU 中有一个 C 结构体,大约有 1000 个元素,它内部包含许多固定大小的数组和其他结构体,现在我想使用 C# 将数据带到 PC 上
这是我在 C 中的结构元素的简单预览
struct _registers
{
char name[32];
float calibrate[4][16];
float DMTI;
float DMTII;
float DMTIII;
float DMTIE;
float DMTIIE;
....
};
现在我想使用 GCHandle 类将 Struct 转换为 C#,
类似的东西
//The C struct is in this byte array named buffer
byte[] buffer = new byte[4096];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
_registers stuff = (protection_registers)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),typeof(_registers));
handle.Free();
问题在于 Visual Studio 抱怨“指针和固定大小的缓冲区只能在不安全的上下文中使用”
有没有办法在没有不安全代码的情况下正常使用它?我发现做这样的事情
[StructLayout(LayoutKind.Explicit, Size = 56, Pack = 1)]
public struct NewStuff
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
[FieldOffset(0)]
public string name;
[MarshalAs(UnmanagedType.U4)]
[FieldOffset(32)]
public float calibrate[4][16];
}
但是随着 MCU 上的代码在未来几年不断发展,我们将在 Struct 中添加大量功能和参数,而且由于 struct 已经有 1000 个元素,我们如何才能做得更好、更聪明呢?因为跟踪所有偏移量非常困难且容易出错!
【问题讨论】:
-
标签垃圾邮件是不好的网络礼仪
-
您不需要指定
FieldOffset,只要您正确定义了所有字段的大小(您正在这样做)。 -
如果
_registers有 1000 个元素,则不应将其声明为struct。改为将其声明为class。否则,每个分配都会创建一个新的_registers副本。 C++中class和struct的区别与C#中class和struct的区别不一样。 -
有没有办法把 SizeConst 也去掉?
-
谢谢,能给我一个狙击密码吗?