C#中结构体与字节流互相转换

1、定义与C++对应的C#结构体

在c#中的结构体不能定义指针,不能定义字符数组,只能在里面定义字符数组的引用。

C++的消息结构体如下:

//消息格式 4+16+4+4= 28个字节

struct cs_message{

u32_t cmd_type;

char username[16];

u32_t dstID;

u32_t srcID;

};

C#定义的结构体如下:

[StructLayout(LayoutKind.Sequential, Pack = 1)]

public struct my_message

{

public UInt32 cmd_type;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]

public string username;

public UInt32 dstID;

public UInt32 srcID;

public my_message(string s)

{

cmd_type = 0;

username = s;

dstID = 0;

srcID = 0;

}

}

在C++的头文件定义中,使用了 #pragma pack 1 字节按1对齐,所以C#的结构体也必须要加上对应的特性,LayoutKind.Sequential属性让结构体在导出到非托管内存时按出现的顺序依次布局,而对于C++的char数组类型,C#中可以直接使用string来对应,当然了,也要加上封送的特性和长度限制。

2、结构体与byte[]的互相转换

定义一个类,里面有2个方法去实现互转:

public class Converter

{

public Byte[] StructToBytes(Object structure)

{

Int32 size = Marshal.SizeOf(structure);

Console.WriteLine(size);

IntPtr buffer = Marshal.AllocHGlobal(size);

try

{

Marshal.StructureToPtr(structure, buffer, false);

Byte[] bytes = new Byte[size];

Marshal.Copy(buffer, bytes, 0, size);

return bytes;

}

finally

{

Marshal.FreeHGlobal(buffer);

}

}

public Object BytesToStruct(Byte[] bytes, Type strcutType)

{

Int32 size = Marshal.SizeOf(strcutType);

IntPtr buffer = Marshal.AllocHGlobal(size);

try

{

Marshal.Copy(bytes, 0, buffer, size);

return Marshal.PtrToStructure(buffer, strcutType);

}

finally

{

Marshal.FreeHGlobal(buffer);

}

}

}

3、测试结果:

static void Main(string[] args)

{

//定义转换类的一个对象并初始化

Converter Convert = new Converter();

//定义消息结构体

my_message m;

//初始化消息结构体

m = new my_message("yanlina");

m.cmd_type = 1633837924;

m.srcID = 1633837924;

m.dstID = 1633837924;

//使用转换类的对象的StructToBytes方法把m结构体转换成Byte

Byte[] message = Convert.StructToBytes(m);

//使用转换类的对象的BytesToStruct方法把Byte转换成m结构体

my_message n = (my_message)Convert.BytesToStruct(message, m.GetType());

//输出测试

Console.WriteLine(Encoding.ASCII.GetString(message));

Console.WriteLine(n.username);

}

结构体的size是28个字节和c++的结构体一样,同时可以将结构体和字节数组互转,方便UDP的发送和接收。

C#中结构体与字节流互相转换

时间: 2024-10-16 02:00:02

C#中结构体与字节流互相转换的相关文章

C#中结构体定义并转换字节数组

最近的项目在做socket通信报文解析的时候,用到了结构体与字节数组的转换:由于客户端采用C++开发,服务端采用C#开发,所以双方必须保证各自定义结构体成员类型和长度一致才能保证报文解析的正确性,这一点非常重要. 首先是结构体定义,一些基本的数据类型,C#与C++都是可以匹配的: [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct Head { public

C++中结构体和类的区别

在C++中,结构体是一种特殊形态的类. 结构体和类的唯一区别就是:  结构体和类具有不同的默认访问控制属性. 类中,对于未指定访问控制属性的成员,其访问控制属性为私有类型(private) 结构体中,对于未指定任何访问控制属性的成员,其访问控制属性为公有类型(public) C++中,不使用结构体丝毫不会影响程序的表达能力.C++之所以要引入结构体,是为了保持和C程序的兼容性. 但有时仍会在C++中使用结构体,是因为,可以使用结构体将不同类型数据组成整体,方便于保存数据.(若用类来保存,因类中成

OpenCV 中结构体IplImage 成员width widthStep使用注意事项

OpenCV 中结构体IplImage 成员width,widthStep使用注意事项 width 是指的图片宽度是多少个像素,而这里widthStep是指的图片中的每一行占用多少个字节. 而且,widthStep会有字节对齐. 当需要对每个像素进行操作的时候,这里最好用widthStep做行递增变换. 比方说这里就是一个例子,明显,ptr_pixel_tmp是指向double类型的三通道图像,而ptr_pixel_img是unsigned char类型的三通道图像,double占八个字节. 于

C /C ++中结构体的定义

c语言中结构体的定义: struct 结构体名{ 成员列表: ..... }结构体变量: 7.1.1 结构体类型变量的定义结构体类型变量的定义与其它类型的变量的定义是一样的,但由于结构体类型需要针对问题事先自行定义,所以结构体类型变量的定义形式就增加了灵活性,共计有三种形式,分别介绍如下:1) 先定义结构体类型,再定义结构体类型变量:struct stu / *定义学生结构体类型* /{char name[20]; / * 学生姓名* /char sex; / * 性别* /long num;

OC类中一些细节问题(对象类存储、类中结构体的用法)

一:OC中得方法名 注意:方法名冒号和后面的and方法名冒号  都是方法名 一:对象的存储细节 类加载到代码区(包括类中得属性和方法).对象动态加载到堆内存中.指向对象的指针存放在栈区. 三:定义类常见的错误 定义类的时候,常见的错误 1)类的定义不能嵌套 2)不要漏写 @end 3) 不要忘记写实现类(如果忘记写了,编译不会报错,运行时候才报错) 4)定义成员变量的大括号经常漏写 5) 如果不写@interface 只有 @implementation 这可以,但是会报警告,建议不要这么写 6

【转载】C++中结构体的声明和定义

http://blog.csdn.net/whuslei/article/details/5665289 1  //定义一个结构体,类型为struct Student 2  struct  Student      3  { 4      string name; 5      double eng; 6      double ch; 7  };  8    9  //定义了一个结构体,类型为struct Student:且定义了一个结构体实例,名叫Stu 10  struct  Studen

C语言中结构体赋值问题的讨论(转载)

今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言中结构体赋值的问题吧: 结构体直接赋值的实现 下面是一个实例: #include <stdio.h> struct Foo { char a; int b; double c; }foo1, foo2; //define two structs with three different field

修改Dictionary或List中结构体struct值的问题

问题:修改Dictionary中结构体struct值的值,如果直接用Dictionary[key].a += XX;(a为结构体中某数值型属性) ,则会报错: 无法修改.Dictionary<int,struct>.this[int]”的返回值,因为它不是变量 如果用一个变量承接Dictionary[key]中的结构体,即struct newStr =Dictionary[key],然后再做出修改:newStr.a += XX,则Dictionary中对应的结构体的值不发生变化.(由此可判断结

Linux C中结构体初始化

    在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式.该方式是某些C教材(如谭二版.K&R二版)中没有介绍过的.这种方式称为指定初始化(designated initializer).下面我们看一个例子,Linux-2.6.x/drivers/usb/storage/usb.c中有这样一个结构体初始化项目: static struct usb_driver usb_storage_driver = { .owner = THIS_MODULE, .name = "