昨晚在群裏無意間看到一個朋友有一個需求。他是在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. java的并发和多线程

    本文主要讲解Java并发相关的内容,包括锁.信号量.堵塞队列.线程池等主要内容. 并发的优点和缺点 在讲述怎么利用多线程的情况下,我们先看一下采用多线程并发的优缺点. 优点 提高资源利用率 如读取一个 ...

  2. hdu 4882 比赛罚时贪心

    http://acm.hdu.edu.cn/showproblem.php?pid=4882 就是CF的比赛,根据时间的推迟会相应的扣掉题目的分数,每个任务有e,k,e表示完成需要时间,k表示完成后消 ...

  3. shell工具-sed

    sed sed是一种流编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕.接着处理下一行,这 ...

  4. AutoCompleteTextView 简单用法

    http://blog.csdn.net/i_lovefish/article/details/17337999

  5. JMS学习以及jms的实现activeMq

    1.JMS规范介绍: http://www.cnblogs.com/hapjin/p/5431706.html http://elim.iteye.com/blog/1893038 http://bl ...

  6. 1.buntu 安装redis

    方式一 :apt安装 在 Ubuntu 系统安装 Redi 可以使用以下命令: $sudo apt-get update $sudo apt-get install redis-server 启动 R ...

  7. 7.与python交互

    与python交互 在熟练使用sql语句的基础上,开始使用python语言提供的模块与mysql进行交互 这是我们在工作中大事要做的事 先学会sql是基础,一定要熟练编写sql语句 安装引入模块 安装 ...

  8. 在Winform中菜单动态添加“最近使用文件”

    最近在做文件处理系统中,要把最近打开文件显示出来,方便用户使用.网上资料有说,去遍历“C:\Documents and Settings\Administrator\Recent”下的最近文档本.文主 ...

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

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

  10. 【BZOJ5188】 [Usaco2018 Jan]MooTube

    BZOJ5188 [Usaco2018 Jan]MooTube 突然发现BZOJ没有题目,放题面. 题意翻译 题面描述 在业余时间,Farmer John创建了一个新的视频共享服务,他将其命名为Moo ...