昨晚在群裏無意間看到一個朋友有一個需求。他是在C裏面將兩個結構體(HeadStruct,BodyStruct)的内存數據直接通過socket send發給C#寫的服務端來處理。當然他之前所使用的需求基本都是從C到C之間進行通信,然後把内存二進制數據再還原到結構上就行。但是C與C#之間可不能簡單就這麽弄。

後來想了一下,大家暫且想出了兩種方案。

  1.還是用C寫一個DLL,直接用C# DllImport這個C的DLL,把Socket接收到的字節數據傳給這個Dll,用這個Dll處理。

  2.使用C#的 unsafe。這種方式是我提出的,因爲之前雖然沒用過unsafe但是感覺應該可行的樣子,下面就是對這种方式測試一下C#裏unsafe struct的内存結構與C的内存結構比較。

(1)首先我們定義C的結構和程序:

#include <stdio.h>

//定義結構類型
typedef struct
{
int x;
int y;
char cs[10];
int z;
} TestStruct; int main()
{
//結構對象
TestStruct ts = { 0 };
ts.x = 10;
ts.y = 20;
ts.z = 30;
for (int i = 0; i < 10; ++i)
{
*(ts.cs + i) = i + 10;
}
//打印内存數據
printf(" C Data(%d):\n",sizeof(ts));
for (int i = 0; i < sizeof(ts); ++i)
{
printf("%d ", *((char*)&ts + i));
}
return 0;
}

  

(2)然後我們定義C#的結構和程序:

using System;

namespace ConsoleApplication
{
/// <summary>
/// 測試結構
/// </summary>
public unsafe struct TestStruct
{
public int x;
public int y;
public fixed byte cs[10];
public int z;
} class Program
{
unsafe static void Main(string[] args)
{
//定義結構對象
TestStruct ts = new TestStruct()
{
x = 10
,
y = 20
,
z = 30
};
for (int i = 0; i < 10; i++)
{
*(ts.cs + i) = (byte)(i + 10);
}
byte[] bs = new byte[sizeof(TestStruct)];
for (int i = 0; i < sizeof(TestStruct); ++i)
{
bs[i] = *(((byte*)&ts) + i);
}
//打印結構數據
Console.WriteLine(string.Format("C# Data({0}):", sizeof(TestStruct)));
for (int i = 0; i < sizeof(TestStruct); ++i)
{
Console.Write(*(((byte*)&ts) + i));
Console.Write(" ");
}
Console.ReadLine();
}
}
}

  

(3)接下來就是看結果的時候了,呵呵(兩張圖):

C   結果:

C# 結果:

\

結果: 可以看到兩個結構的内存大小都是24字節,並且字段的位置分佈也一致。藍色區域表示兩個結構字段的内存。紅色區域便是内存對齊數據了。總之此次測試還是有收穫的。

比較C struct 與 C# unsafe struct内存分佈的更多相关文章

  1. Python socket编程之二:【struct.pack】&【struct.unpack】

    import struct """通过 socket 的 send 和 recv 只能传输 str 格式的数据""" "" ...

  2. 通过 struct 成员地址 获取 struct 结构体地址

    1. 问题描述: 现在定义了一个结构体: struct Foo { int a; int b; }; Foo foo; 假如由于函数传参等原因,现在程序只能拿到 foo.b 的地址,这时想通过某种方法 ...

  3. 2. struct A 和 typedef struct A

    2. struct A 和 typedef struct A 2.1 struct A struct A{}定义一个名为struct A的结构体. 下例定义了struct A同时,声明了两个变量(注意 ...

  4. python中struct.pack()函数和struct.unpack()函数

    python中的struct主要是用来处理C结构数据的,读入时先转换为Python的字符串类型,然后再转换为Python的结构化类型,比如元组(tuple)啥的~.一般输入的渠道来源于文件或者网络的二 ...

  5. C# unsafe模式内存操作深入探索

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...

  6. 危险代码:如何使用Unsafe操作内存中的Java类和对象

    危险代码:如何使用Unsafe操作内存中的Java类和对象—Part1 危险代码:如何使用Unsafe操作内存中的Java类和对象—Part2 危险代码:如何使用Unsafe操作内存中的Java类和对 ...

  7. C++中class与struct的区别(struct的类型名同时可以作为变量名)

    通常我们知道的区别: (一)默认继承权限.如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理: (二)成员的默认访问权限.class的成员默 ...

  8. typedef struct xxx xxx与struct xxx区别 && “->”和“.”访问结构体变量

    1. struct //是C中的结构体的关键词.如: stuct node{ int a;.....} a; node 相当于结构体的类型,关键是其实在C中stuct node 才相当于一个数据类型, ...

  9. C语言中 struct成员变量顺序对内存的占用

    在C语言的结构体中,是会按照其变量类型来进行分配内存大小的.但是对于不同的编译器,结果是不同的,在VC++6.0中是怎么个分配情况呢?用一下C中的关键字sizeof()来测试下,注意sizeof()不 ...

随机推荐

  1. 通过mybatis向数据库中插入日期数据

    遇到的问题: 通过mybatis向数据库中插入日期格式数据,发现只有年月日, 没有小时分钟和秒 当你想在实体类中使用java.util.Date类型,而且还想在数据库中保存时分秒时, 解决办法: 你可 ...

  2. (原创)用c++11打造好用的any

    上一篇博文用c++11实现了variant,有童鞋说何不把any也实现一把,我正有此意,它的兄弟variant已经实现了,any也顺便打包实现了吧.其实boost.any已经挺好了,就是转换异常时,看 ...

  3. 实验5 IIC通讯与AD/接DA接口

    1.利用单片机控制PCF8591的AD转换,控制AD0和AD1电位器,在数码光上显示DA转换的值. 2.利用单片机控制PCF8591的DA转换,让发光二极管D1由暗到亮变化,整个过程时间差不多2s左右 ...

  4. WPF实战案例-数据代理

    在我们wpf开发中,很多人会有mvvm模式去做wpf的项目. 是否有人遇到这样一个场景:在一个界面上,有个tabcontrol上面有4个页签,每个页签里面都有一个datagrid,里面显示的列基本一样 ...

  5. OCP 062大量考试新题(2019年)-12

    12. Your database is configured in archivelog mode. Examine the RMAN configuration parameters: CONFI ...

  6. iOS开发-自动隐藏键盘及状态栏

    1.隐藏状态栏 iOS升级至7.0以后,很多API被废止,其中原有隐藏状态栏StatusBar的方法就失效了. 原有方案 [[UIApplication sharedApplication] setS ...

  7. 微信公众平台主动推送消息(asp.net)

    /// <summary>        /// MD5 32位加密        /// </summary>        /// <param name=" ...

  8. 56.storm 之 hello world (集群模式)

    回顾 在上一小节,我们在PWTopology1 这一个java类中注解掉了集群模式,使用本地模式大概了解一下storm的工作流程.这一节我们注解掉本地模式相关的代码,放开集群模式相关代码,并且将项目打 ...

  9. python爬虫----XPath

    1.知道本节点元素,如何定位到兄弟元素 详情见博客 XML代码见下 bt1在文档中只出现一次,所以很容易获取到bt1中内容,那怎么根据<td class='bt1'>来获取bt2中的内容 ...

  10. cpu负载的探讨 (转)

    文章出处:http://blog.chinaunix.net/uid-12693781-id-368837.html 摘要:确定cpu的负载的定义,帮助管理员设置cpu负载阀值,推测可能的导致cpu负 ...