我们有COM服务器(作为dll,我们只有dll文件),它实现了两个COM接口。其中一个接口允许我们从某个设备获取消息(作为结构)。根据消息,我们需要处理相应的结构。每个结构都指向结构 VARIANT 。此结构的类型为字节数组(VT_ARRAY | VT_UI1)。
所有结构都包含结构Header
和其他一些信息。结构Header
包含字段MsgId
。根据{{1}},我们需要处理其他结构。
为了从dll到c#获取结构,我们使用反射。
现在,是时候了:
MsgId
我们每100毫秒通过反射从设备获取数据:
// 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;
}
然后我们将 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
结构,我们使用C# array within a struct中提出的方法(进行一些编辑):
Header
我们如何使用一个:
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
这里我们得到例外:无法编组“Main”类型的字段“h”。托管/非托管类型组合无效(此值类型必须与Struct配对)
我们尝试将内部结构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;
}
}
的{{1}}声明更改为
MarshalAsAttribute
和
h
但它不起作用。如果可能,我们如何从[MarshalAsAttribute(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_SAFEARRAY)]
结构中获取数据?
答案 0 :(得分:-2)
字节通过BinaryReading
读取是我现在的解决方案。一切都很好。谢谢大家!