gpt4 book ai didi

c# - 在 C# 中正确编码 C++ 结构

转载 作者:太空宇宙 更新时间:2023-11-04 13:20:20 24 4
gpt4 key购买 nike

我在 C++ 中有这个结构,我需要将其转换为 C#,因此我可以从 byte[] 创建这个结构。

struct  TRANS_RECORD_DATA {
int size, code;
int ThrowItemCount;
int ItemCount;
int ItemSubStart;
int DataSize;
BYTE Data[sizeof(sRECORD_ITEM) * 200]; // sizeof(sRECORD_ITEM) = 548
};

C# 版本:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TRANS_RECORD_DATA {
public int size, code;
public int ThrowItemCount;
public int ItemCount;
public int ItemSubStart;
public int DataSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 548*200)]
public byte[] Data;
};

我正在使用这个通用函数从字节数组中获取结构:

T ByteArrayToStructure<T>(byte[] bytes) where T : struct
{
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T stuff = (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof (T));
handle.Free();
return stuff;
}

但它给了我:

AccessViolation Exception.

我相信我知道为什么,但我不知道如何解决。 byte[] 我有,需要映射到结构中,并不总是具有大小为 548*200 的 Data 成员。这个数字是最大值。但似乎我使用的那个 GenericMethod 总是尝试用该数据创建结构,该数据总是 548 * 200,然后它显然会抛出 AccessViolation,因为要映射的数据已经结束。

例如这段代码:

var bytes = new byte[26];
var structure = ByteArrayToStructure<TRANS_RECORD_DATA>(bytes);

应该返回一个 TRANS_RECORD_DATA,其中所有 int 成员的值为 0,最后 byte[] Data 将只有剩下的两个字节。 (26 - 24 = 2)。但它似乎一直试图创建完整的 548*200 byte[],然后导致访问冲突。

有办法解决吗?

最佳答案

因此,正如您所解释的那样,无论数据数组的 C 定义为 200*548 字节长,它实际上并未完全分配或由您调用的外部非托管代码填充。

这样,您唯一的解决方法就是不在 C# 结构定义中定义数据:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TRANS_RECORD_DATA {
public int size, code;
public int ThrowItemCount;
public int ItemCount;
public int ItemSubStart;
public int DataSize;
};

并在读取 DataSize 后将字节数组的其余部分重新解释为该数据结构。

您仍然可以使用对 Marshal.PtrToStructure 的一系列调用:

GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
TRANS_RECORD_DATA stuff = (TRANS_RECORD_DATA) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof (TRANS_RECORD_DATA));
var items = new List<sRECORD_ITEM>(stuff.ItemCount);
for (int i = 0; i < stuff.ItemCount; ++i)
{
var ptr = handle.AddrOfPinnedObject().Add(i*548)
sRECORD_ITEM item = (sRECORD_ITEM)Marshal.PtrToStructure(ptr,typeof(sRECORD_ITEM));
}

我很确定这应该可以解决问题。

关于c# - 在 C# 中正确编码 C++ 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35592985/

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