比較C struct 與 C# unsafe struct内存分佈
昨晚在群裏無意間看到一個朋友有一個需求。他是在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内存分佈的更多相关文章
- Python socket编程之二:【struct.pack】&【struct.unpack】
import struct """通过 socket 的 send 和 recv 只能传输 str 格式的数据""" "" ...
- 通过 struct 成员地址 获取 struct 结构体地址
1. 问题描述: 现在定义了一个结构体: struct Foo { int a; int b; }; Foo foo; 假如由于函数传参等原因,现在程序只能拿到 foo.b 的地址,这时想通过某种方法 ...
- 2. struct A 和 typedef struct A
2. struct A 和 typedef struct A 2.1 struct A struct A{}定义一个名为struct A的结构体. 下例定义了struct A同时,声明了两个变量(注意 ...
- python中struct.pack()函数和struct.unpack()函数
python中的struct主要是用来处理C结构数据的,读入时先转换为Python的字符串类型,然后再转换为Python的结构化类型,比如元组(tuple)啥的~.一般输入的渠道来源于文件或者网络的二 ...
- C# unsafe模式内存操作深入探索
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...
- 危险代码:如何使用Unsafe操作内存中的Java类和对象
危险代码:如何使用Unsafe操作内存中的Java类和对象—Part1 危险代码:如何使用Unsafe操作内存中的Java类和对象—Part2 危险代码:如何使用Unsafe操作内存中的Java类和对 ...
- C++中class与struct的区别(struct的类型名同时可以作为变量名)
通常我们知道的区别: (一)默认继承权限.如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理: (二)成员的默认访问权限.class的成员默 ...
- typedef struct xxx xxx与struct xxx区别 && “->”和“.”访问结构体变量
1. struct //是C中的结构体的关键词.如: stuct node{ int a;.....} a; node 相当于结构体的类型,关键是其实在C中stuct node 才相当于一个数据类型, ...
- C语言中 struct成员变量顺序对内存的占用
在C语言的结构体中,是会按照其变量类型来进行分配内存大小的.但是对于不同的编译器,结果是不同的,在VC++6.0中是怎么个分配情况呢?用一下C中的关键字sizeof()来测试下,注意sizeof()不 ...
随机推荐
- unidbgrid列排序
unidbgrid列排序 1)指定列的.sortable:=true; 2)unidbgrid.columnsort事件添加如下代码: if SameText(Column.FieldName, 'I ...
- cxgrid显示海量数据
cxgrid显示海量数据 在默认情况下,cxgrid显示几万条以上的数据会很慢.怎么办? 交下面的属性设为TRUE以后,速度飞快. 但速度是快了,自动计算列的合计值这些功能却失效了,正所谓有得必有失!
- 怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- Android-Recyclerview-GridView&瀑布流等效果
由于Recyclerview是在 android.support.v7.widget.包 RecyclerView,所以需要导Recycler库: 导Recycler库: 选择项目,右键--> ...
- bash编程-Shell基础
1. Shell脚本执行方式 直接运行,需要在脚本文件头部指定解释器,如#!/bin/bash ./myshell.sh 运行时指定shell解释器 bash myshell.sh 2. Shell命 ...
- 二、基于kubernetes构建Docker集群环境实战
kubernetes是google公司基于docker所做的一个分布式集群,有以下主件组成 etcd: 高可用存储共享配置和服务发现,作为与minion机器上的flannel配套使用,作用是使每台 m ...
- JS学习笔记6_事件
1.事件冒泡 由内而外的事件传播(从屏幕里飞出来一支箭的感觉) 2.事件捕获 由表及里的事件传播(力透纸背的感觉) 3.DOM事件流(DOM2级) 事件捕获阶段 -> 处于目标阶段 -> ...
- UCore-Lab0
日期:2019/3/31 内容:UCore-Lab0 一.UCore实验 实验 说明 关键词 Lab1 bootloader的实现 中断 Lab2 物理内存管理 x86分段/分页模式 Lab3 虚拟内 ...
- pycharm光标变成黑框,恢复成竖线
pycharm光标变成黑框,如下图所示 解决办法: 按外接键盘上的Insert键,即可恢复.
- 详述MSSQL服务在渗透测试中的利用 (下篇)
part3 MSSQL写文件 步骤1 sp_makewebtask写文件 因为是`SA`权限,如果目标服务器是web服务器,我们也不用去备份了,可以直接写个一句话木马进去到web目录. 在不知道web ...