昨晚在群裏無意間看到一個朋友有一個需求。他是在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的結構和程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#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#的結構和程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
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字節,並且字段的位置分佈也一致。藍色區域表示兩個結構字段的内存。紅色區域便是内存對齊數據了。總之此次測試還是有收穫的。