昨晚在群裏無意間看到一個朋友有一個需求。他是在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字節,並且字段的位置分佈也一致。藍色區域表示兩個結構字段的内存。紅色區域便是内存對齊數據了。總之此次測試還是有收穫的。
比較C struct 與 C# unsafe struct内存分佈
原文:http://www.cnblogs.com/Rainr/p/3535620.html