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#中结构体与字节流互相转换的更多相关文章

  1. C# 将结构体转为字节流的方式

    1. 将基础类型转为byte数组存储 private byte[] CreateNetDataByteStream(ushort system, ushort host, ushort type, b ...

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

    最近的项目在做socket通信报文解析的时候,用到了结构体与字节数组的转换:由于客户端采用C++开发,服务端采用C#开发,所以双方必须保证各自定义结构体成员类型和长度一致才能保证报文解析的正确性,这一 ...

  3. (一)一个工作任务引起的乱战——c#中结构体与byte[]间相互转换

    一个工作任务涉及到c#与c++系统间的udp通信,处理了蛮长时间没有完成任务,但是期间接触到不少小知识点.本人是初接触c#,c++语言没有接触过.可能写的东西都很小儿科,暂且记录下来当工作日记把. 先 ...

  4. STM32L0系列EEPROM中结构体的读取

    在STM32L0中操作EEPROM本来参考了上篇操作FLASH的方法,多多少少都有些问题.我觉得可能是结构体在转换成其他变量的时候出了问题. 比如下面这段代码,在Windows上可以正常运行(使用g+ ...

  5. C语言中结构体赋值问题的讨论

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

  6. OC中结构体作为对象属性

    在OC中结构体有时候也作为对象的属性 类的定义 #import <Foundation/Foundation.h> typedef struct{ int year; int month; ...

  7. C语言中结构体对齐问题

    C语言中结构体对齐问题 收藏 关于C语言中的结构体对齐问题 1,比如: struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B; ...

  8. C C++ 中结构体与类

    先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...

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

    今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言 ...

随机推荐

  1. Java解析XMl文件之SAX和DOm方法

    如题,这两种方法的jar包都在jdk中,不需要下载. 先来说下目录结构: 首先建一个Peron类封装person.xml的属性:DomParseService和SaxParseService分别为两种 ...

  2. jBPM - Eclipse 安装 jBPM 插件

    假设 jBPM 包的解压路径为 E:/jbpm-installer,Eclipse 的安装目录为 E:/eclipse. 安装 jBPM 插件 1. 将 E:/jbpm-installer/lib 目 ...

  3. Android中android-async-http开源网络框架的简单使用

    android-async-http开源网络框架是专门针对Android在Apache的基础上构建的异步且基于回调的http client.所有的请求全在UI线程之外发生,而callback发生在创建 ...

  4. C# winform 选择项 省市连动

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. Java Mail发送简单邮件,完整代码

    依赖javax.mail.jar,地址:https://java.net/projects/javamail/pages/Home 完整示例代码如下: package com.jadic.utils; ...

  6. 高性能CSS(二)

    避免CSS表达式 CSS表达式是动态设置CSS属性的强大(但危险)方法.Internet Explorer从第5个版本开始支持CSS表达式.下面的例子中,使用CSS表达式可以实现隔一个小时切换一次背景 ...

  7. 页面get请求 中文参数方法乱码问题

    对于get方式,请求参数中存在中文,可以使用下面的方法进行处理: 两次使用encodeURI()方法:例如:encodeURI(encodeURI(“中文”)),然后再服务器中使用URLDecoder ...

  8. 《java编程思想》--多线程基础--Runnable

    一.简单说下Runnable是什么 1.它是一个接口 2.只提供了run方法 3.这个接口提供了一个协议:实现这个接口的类是active的(不必成为Thread的子类) 4.run方法没有返回值 /* ...

  9. HTML5+J2EE实现文件异步上传

    P.S. HTML5经过了W3C的8年努力,终于正式推广了.这次升级最大的就是升级了XMLHTTPRequest,让它变成了XMLHTTPRequest Level II(这有啥奇怪的?).这个对象现 ...

  10. RHEL6.3 ftp服务器参数的戏说——不看白不看,看了不白看

    大家都知道ftp服务器的应用何止广,简直就是无处不在,配置简单的ftp服务谁都会,无外乎就是刚安装好ftp服务,一启动就ok了:或是达到简单的上传下载修改下/var/ftp/pub的权限,配合配置文件 ...