gpt4 book ai didi

c# - 将嵌套结构编码到 C#

转载 作者:太空宇宙 更新时间:2023-11-03 17:05:49 25 4
gpt4 key购买 nike

我们有 COM 服务器(作为 dll,我们只有 dll 文件),它实现了两个 COM 接口(interface)。其中一个接口(interface)允许我们从某个设备获取消息(作为结构)。根据消息,我们需要处理相应的结构。每个结构都是指向结构VARIANT 的指针。此结构的类型为字节数组(VT_ARRAY | VT_UI1)

所有结构都包含结构Header 和一些其他信息。结构 Header 包含字段 MsgId。根据 MsgId,我们需要处理其他结构。

为了获取从 dll 到 c# 的结构,我们使用反射。

现在,是时候举个例子了:

// Header (sub-struct of main struct) - 
[StructLayout(LayoutKind.Sequential)]
public struct Header
{
public int MsgId;
}

// main struct
[StructLayout(LayoutKind.Sequential)]
public struct Main
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct)]
public Header h;
public int count;
}

每 100 毫秒我们通过反射从设备获取数据:

   private bool ReadMessage(ref object msg)
{
object _msg = null;
object[] args = new Object[] { _msg };

ParameterModifier byRefParamMod = new ParameterModifier(1);

byRefParamMod[0] = true;

ParameterModifier[] pmArray = { byRefParamMod };

var value = SomeWrapper.CallMethod(ClientInstance, "ReadMessage", args, pmArray);

msg = args[0];

return ((int)value == S_OK) ? true : false;
}

然后我们将 msg 转换为 byte[] 然后我们需要将字节数组转换为我们的结构。在这个地方,我们在编码方面遇到了一些问题。

正如我所写的,为了定义我们需要处理的结构(换句话说我们需要编码)首先我们需要编码Header结构是包含在所有结构中(换句话说,在来自设备的所有消息中)。

为了编码 Header 结构,我们使用 C# array within a struct 中提出的方法(经过一些编辑):

 public static T DeserializeMsg<T>(byte[] msg) where T : struct
{
// Pin the managed memory while, copy it out the data, then unpin it
GCHandle handle = GCHandle.Alloc(msg, GCHandleType.Pinned);
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();

return theStructure;
}

我们如何使用一个:

 private void ProcessMessage(byte[] message)
{
Header msgHeader = new Header();
msgHeader = DeserializeMsg<Header>(message);
}

一切正常!这里我们得到了msgHeader.MsgId 然后我们需要得到另外一个结构体:

private void ProcessMessage(byte[] message)
{
Header msgHeader = new Header();
msgHeader = DeserializeMsg<Header>(message);

switch (msgHeader.MsgId)
{
case START:
Main msgMain = new Main();
// Here we get exception (see below)
msgMain = DeserializeMsg<Main>(message);
break;
default:
break;
}
}

这里出现异常:无法编码“Main”类型的字段“h”。无效的托管/非托管类型组合(此值类型必须与 Struct 配对)

我们已尝试将内部结构 hMarshalAsAttribute 声明更改为

[MarshalAsAttribute(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_SAFEARRAY)]

[MarshalAsAttribute (UnmanagedType.SafeArray, SafeArrayUserDefinedSubType=typeof(Header))]

但它不起作用。如果可能,我们如何从 Main 结构中获取数据?

最佳答案

逐字节 通过 BinaryReading 读取是我现在的解决方案。一切正常。感谢大家!

关于c# - 将嵌套结构编码到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20246459/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com