比較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):
",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字節,並且字段的位置分佈也一致。藍色區域表示兩個結構字段的内存。紅色區域便是内存對齊數據了。總之此次測試還是有收穫的。

原文地址:https://www.cnblogs.com/rainrcn/p/3535620.html