1 using System.Runtime.InteropServices;
2
3 #region 需要转换的结构
4 [StructLayout(LayoutKind.Sequential, Pack=1)]//struTest变量在内存中的对齐方式 (指针类型转换成功的必要条件)
5 public struct struTest{
6 public int intId;
7 public int intName;
8 public DateTime dtBegintime;
9 }
10 #endregion
11
12 /// <summary>
13 /// xamConverter 的摘要说明。 特定结构变量和byte[]之间的转换操作
14 /// author:xam
15 /// date:2007-4-23
16 /// note:apply convertion functions to deal with convertion between struct value and byte [] value;
17 /// </summary>
18 public class xamConverter
19 {
20 #region 构造函数
21 public xamConverter()
22 {
23
24 //
25 // TODO: 在此处添加构造函数逻辑
26 //
27 }
28 #endregion
29
30 #region 方式一 通过指针类型的强制转换
31
32 #region 结构变量到byte[]的转换
33 /// <summary>
34 /// 结构变量到byte[]的转换
35 /// </summary>
36 /// <param name="s">结构变量</param>
37 /// <returns>byte[](已分配空间)</returns>
38 public unsafe byte[] xamStructToBytes( struTest s ) {
39 byte[] arr = new byte[ sizeof(struTest) ];
40 fixed( byte* parr = arr ) {
41 *((struTest*)parr) = s; }
42 return arr;
43 }
44 #endregion
45
46 #region byte[] 到结构变量的转换
47 /// <summary>
48 /// byte[] 到结构变量的转换
49 /// </summary>
50 /// <param name="arr">byte[]</param>
51 /// <returns>结构变量</returns>
52 public unsafe struTest xamBytesToStruct( byte[] arr ) {
53 if( arr.Length < sizeof(struTest) )
54 throw new ArgumentException();
55
56 struTest s;
57 fixed( byte* parr = arr ) {
58 s = *((struTest*)parr); }
59 return s;
60 }
61 #endregion
62
63 #region 结构变量数组到byte[]的转换
64 /// <summary>
65 /// 结构变量数组到byte[]的转换
66 /// </summary>
67 /// <param name="s">结构变量数组</param>
68 /// <param name="tSize">结构变量数组的大小</param>
69 /// <returns>byte[]</returns>
70 public unsafe byte[] xamStructToBytes( struTest[] s,int tSize ) {
71 int i;
72 byte[] arr = new byte[ sizeof(struTest)*tSize ];
73 for(i=0;i<tSize;i++){
74
75 fixed( byte* parr = arr ) {
76
77 (((struTest*)parr)[i]) = s[i];
78 }
79 }
80 return arr;
81 }
82 #endregion
83
84 #region byte[] 到结构变量数组的转换
85 /// <summary>
86 /// byte[] 到结构变量数组的转换
87 /// </summary>
88 /// <param name="arr">byte[]</param>
89 /// <param name="tSize">byte[]包含的结构变量数组的大小</param>
90 /// <returns></returns>
91 public unsafe struTest[] xamBytesToStruct( byte[] arr,int tSize ) {
92 if( arr.Length < sizeof(struTest)*tSize )
93 throw new ArgumentException();
94 int i;
95 struTest[] s = new struTest[tSize];
96
97
98 for(i=0;i<tSize;i++){
99
100 fixed( byte* parr = arr ) {
101
102 s[i] = (((struTest*)parr)[i]);
103 }
104 }
105 return s;
106
107 }
108 #endregion
109
110 #endregion
111
112 #region 方式二
113
114 #region 结构变量到byte[]的转换
115 /// <summary>
116 /// 结构变量到byte[]的转换
117 /// </summary>
118 /// <param name="s">结构变量</param>
119 /// <returns>byte[](已分配空间)</returns>
120 public unsafe byte[] xamStructToBytesB( struTest s ) {
121
122 int size = Marshal.SizeOf(s);
123
124 System.IntPtr ptr = Marshal.AllocHGlobal(size);
125
126 Marshal.StructureToPtr(s, ptr,true);
127 byte[] ba=new byte[size];
128
129 Marshal.Copy(ptr, ba, 0, ba.Length );
130
131 return ba;
132 }
133 #endregion
134
135 #region byte[] 到结构变量的转换
136 /// <summary>
137 /// byte[] 到结构变量的转换
138 /// </summary>
139 /// <param name="arr">byte[]</param>
140 /// <returns>结构变量</returns>
141 public unsafe struTest xamBytesToStructB( byte[] arr ) {
142
143 struTest struReturn=new struTest();
144
145 int size = Marshal.SizeOf(struReturn);
146
147 System.IntPtr ptr = Marshal.AllocHGlobal(size);
148 Marshal.Copy(arr,0,ptr,arr.Length);
149
150 struReturn = (struTest)Marshal.PtrToStructure(ptr,struReturn.GetType());
151
152
153 return struReturn;
154
155 }
156 #endregion
157
158 #region 结构变量数组到byte[]的转换
159 /// <summary>
160 /// 结构变量数组到byte[]的转换
161 /// </summary>
162 /// <param name="s">结构变量数组</param>
163 /// <param name="tSize">结构变量数组的大小</param>
164 /// <returns>byte[]</returns>
165 public unsafe byte[] xamStructToBytesB( struTest[] s,int tSize ) {
166 int i;
167 int size = Marshal.SizeOf(s[0])*s.Length;
168
169 System.IntPtr [] ptrs = new IntPtr[s.Length];
170
171 for(i=0;i<tSize;i++){
172 ptrs[i] = Marshal.AllocHGlobal(size);
173 Marshal.StructureToPtr(s[i], ptrs[i],true);
174 }
175
176
177
178 byte[] ba=new byte[size];
179
180 for(i=0;i<tSize;i++){
181 Marshal.Copy(ptrs[i], ba, i*Marshal.SizeOf(s[0]), Marshal.SizeOf(s[0]) );
182 }
183 return ba;
184 }
185 #endregion
186
187 #region byte[] 到结构变量数组的转换
188 /// <summary>
189 /// byte[] 到结构变量数组的转换
190 /// </summary>
191 /// <param name="arr">byte[]</param>
192 /// <param name="tSize">byte[]包含的结构变量数组的大小</param>
193 /// <returns></returns>
194 public unsafe struTest[] xamBytesToStructB( byte[] arr,int tSize ) {
195 if( arr.Length < sizeof(struTest)*tSize )
196 throw new ArgumentException();
197
198
199 struTest[] struReturn=new struTest[tSize];
200 int intUnitSize = Marshal.SizeOf(struReturn[0]);
201 int size = intUnitSize*tSize;
202
203 int i;int intTemp;
204
205 System.IntPtr [] ptrs = new IntPtr[tSize];
206 for(i=0;i<tSize;i++){
207 intTemp = i*intUnitSize;
208 ptrs[i] = Marshal.AllocHGlobal(size);
209 Marshal.Copy(arr,intTemp,ptrs[i],intUnitSize);
210 struReturn[i] = (struTest)Marshal.PtrToStructure(ptrs[i],struReturn[i].GetType());
211 }
212
213
214 return struReturn;
215
216 }
217 #endregion
218
219 #endregion
220
221 }
222
223 //使用unsafe code 不安全代码选项需打开
224
225 //演示
226
227 #region 结构数组测试
228 xamConverter xc = new xamConverter();
229 struTest[] st = new struTest[3];
230 st[0].intId = 1;
231 st[0].intName = 12;
232 st[0].dtBegintime = DateTime.Now;
233
234 st[2].intId = 2;
235 st[2].intName = 232;
236 st[2].dtBegintime = DateTime.Now;
237
238 byte [] inputBytes = xc.xamStructToBytesB(st,3);
239 struTest[] st2 = xc.xamBytesToStructB(inputBytes,3);
240
241 MessageBox.Show(st2[2].dtBegintime.ToString() + " = " + st2[2].intName.ToString());
242 #endregion