我正在编写一个程序,它将通过UDP与C程序通信 . 另一个程序已经写好了(不是我) . 我有一个.h文件,它定义了两个用于数据的结构 .
编辑:这意味着我无法更改数据格式 . 我需要能够根据C .h文件结构进行读写!
我怎么用C#做这个?我将以这种格式发送和接收数据 .
struct mdata
{
uint32_t mark_kupnr;
uint16_t mark_provnr;
uint16_t markriktning;
uint16_t xpos;
uint16_t ypos;
};
typedef struct
{
uint32_t kupnr;
uint16_t lngd;
uint16_t bredd;
uint16_t tjocklek;
char slagkraft;
uint8_t antal;
struct mdata mark[10];
} markdata;
编辑:我试图在C#中创建相应的结构,但它不起作用
顺便说一句,我在Windows上运行,而C程序在Linux上运行 . 在“规范”中,它表示数据应该是Little Endian .
struct mdata
{
UInt32 mark_kupnr;
UInt16 mark_provnr;
UInt16 markriktning;
UInt16 xpos;
UInt16 ypos;
};
typedef struct
{
UInt32 kupnr;
UInt16 lngd;
UInt16 bredd;
UInt16 tjocklek;
char slagkraft;
byte antal;
// here I have some trouble
mdata[] mark[10]; //???
} markdata;
3 回答
听起来好像你正在寻找fixed keyword . C#中的
char
也是C中char
的两倍,因此您需要使用正确的相应类型sbyte
.这是你的第二个结构的定义方式:
如果您得到错误的值,请检查它们是否是字节交换的 . 但基于使用的系统和数据格式规范,默认情况下,字节序很可能是正确的 .
如果将结构序列化为与平台无关的格式,则可以避免所有容易出错和低级别的数据对齐问题 .
考虑使用Google Protocol Buffers或Apache Thrift自动生成序列化/反序列化代码 . 这些工作整齐地跨越多种语言和数据类型,被广泛使用(测试和调试) . 这些库中的每一个都要求您以与Microsoft IDL类似的格式保留结构的主蓝图 . 然后,您可以轻松地为任何语言生成互操作代码 .
我个人对这两个库都是个问题,所以我选择将数据序列化为JSON format并通过线路发送/接收JSON作为0终止字符串 . 我使用了小的,仅限 Headers 的RapidJSON C库,并使用RapidJSON手动实现了序列化和反序列化代码 .
如果您的C程序主机是IBM-PC兼容机器,则必须在C#客户端上执行字节交换 . 如果不是你必须没有 .
要与C#程序通信,必须将读取的数据反转为大于1个字节,因为C#使用big-endian字节顺序而不是本地C的little-endian . 要交换WORD(16位)和DWORD(32位),您可以使用此宏
或C#中的类似功能 . 仅适用于单独的结构字段 .
PS:不要忘记编译器打包功能来纠正双方的数据含义 .
欲了解更多信息,请访问Endianness,Data structure alignment
所以人们要求我在C#中做同样的事情
使用C#结构
client
表示UDPClient
对象 . 这一切都必须以低级别的方式进行 .表格输出数据必须从
UInt32
和UInt16
反向到字节数组 . 然后使用List<byte>.AddRange(variable_byte_array);
以正确的顺序合并所有这些,而不是将此形成的列表转换为字节数组并使用UDPClient.Send(formed_array);
.C中的数组按此顺序放置在内存中
[0][1][2][3][4][5][6][7][8][9]
. 所以你必须从0到9之间连续读取10次mdata结构 .没有人认为你使用类而不是结构 . 考虑到我们完全使用字节(二进制)序列化,处理数组会更简单 . 比添加到每个类适当的方法(例如)
mdata类或结构方法
您的
markdata
类中的数组不会被修复,因此您只需在类中创建所需数量的元素即可 . 所有脏工作都将转到发送和接收方法 .要处理数组,您可以添加字节移位值来逐步执行
mdata
数组 .