2 // Tests for Marshal.StructureToPtr and PtrToStructure
7 using System
.Runtime
.InteropServices
;
12 [StructLayout (LayoutKind
.Sequential
)]
13 public class SimpleObj
{
17 public void test () {}
20 [StructLayout (LayoutKind
.Sequential
)]
21 public struct SimpleStruct2
{
26 [StructLayout (LayoutKind
.Sequential
, CharSet
=CharSet
.Ansi
)]
27 public struct SimpleStruct
{
32 [MarshalAs (UnmanagedType
.ByValArray
, SizeConst
=2)] public short[] a1
;
33 [MarshalAs (UnmanagedType
.ByValTStr
, SizeConst
=4)] public string s1
;
34 public SimpleStruct2 emb1
;
35 public SimpleObj emb2
;
38 [MarshalAs (UnmanagedType
.ByValArray
, SizeConst
=2)] public char[] a2
;
41 [StructLayout (LayoutKind
.Sequential
, CharSet
=CharSet
.Ansi
)]
42 public struct ByValTStrStruct
{
43 [MarshalAs (UnmanagedType
.ByValTStr
, SizeConst
=4)] public string s1
;
47 [StructLayout (LayoutKind
.Sequential
, CharSet
=CharSet
.Unicode
)]
48 public struct ByValWStrStruct
{
49 [MarshalAs (UnmanagedType
.ByValTStr
, SizeConst
=4)] public string s1
;
53 [StructLayout (LayoutKind
.Sequential
, Pack
=1)]
54 public struct PackStruct1
{
58 [StructLayout (LayoutKind
.Sequential
)]
59 public struct PackStruct2
{
64 [StructLayout (LayoutKind
.Sequential
)]
65 struct InvalidArrayForMarshalingStruct
67 // Missing the following needed directive
68 // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
69 public readonly char[] CharArray
;
72 [StructLayout(LayoutKind
.Sequential
)]
73 struct TwoDimensionalArrayStruct
75 public TwoDimensionalArrayStruct(int[,] vals
)
77 TwoDimensionalArray
= vals
;
80 [MarshalAs(UnmanagedType
.ByValArray
, SizeConst
= 6)]
81 public readonly int[,] TwoDimensionalArray
;
84 public unsafe static int Main (String
[] args
) {
85 if (TestDriver
.RunTests (typeof (Tests
), args
) != 0)
90 public static int test_0_structure_to_ptr () {
91 SimpleStruct ss
= new SimpleStruct ();
92 int size
= Marshal
.SizeOf (typeof (SimpleStruct
));
97 IntPtr p
= Marshal
.AllocHGlobal (size
);
102 ss
.a1
= new short [2];
106 ss
.emb1
= new SimpleStruct2 ();
109 ss
.emb2
= new SimpleObj ();
112 ss
.s2
= "just a test";
114 ss
.a2
= new char [2];
118 Marshal
.StructureToPtr (ss
, p
, false);
119 Type t
= ss
.GetType ();
121 if (Marshal
.ReadInt32 (p
, (int)Marshal
.OffsetOf (t
, "a")) != 1)
123 if (Marshal
.ReadInt32 (p
, (int)Marshal
.OffsetOf (t
, "bool1")) != 1)
125 if (Marshal
.ReadInt32 (p
, (int)Marshal
.OffsetOf (t
, "bool2")) != 0)
127 if (Marshal
.ReadInt32 (p
, (int)Marshal
.OffsetOf (t
, "b")) != 2)
129 if (Marshal
.ReadInt16 (p
, 16) != 6)
131 if (Marshal
.ReadInt16 (p
, 18) != 5)
133 if (Marshal
.ReadByte (p
, 20) != 97)
135 if (Marshal
.ReadByte (p
, 21) != 98)
137 if (Marshal
.ReadByte (p
, 22) != 99)
139 if (Marshal
.ReadByte (p
, 23) != 0)
141 if (Marshal
.ReadInt32 (p
, 24) != 3)
143 if (Marshal
.ReadInt32 (p
, 28) != 4)
145 if (Marshal
.ReadInt32 (p
, 32) != 10)
147 if (Marshal
.ReadInt32 (p
, 36) != 11)
149 if (Marshal
.ReadByte (p
, (int)Marshal
.OffsetOf (t
, "a2")) != 97)
151 if (Marshal
.ReadByte (p
, (int)Marshal
.OffsetOf (t
, "a2") + 1) != 98)
154 SimpleStruct cp
= (SimpleStruct
)Marshal
.PtrToStructure (p
, ss
.GetType ());
159 if (cp
.bool1
!= true)
162 if (cp
.bool2
!= false)
189 if (cp
.s2
!= "just a test")
195 if (cp
.a2
[0] != 'a')
198 if (cp
.a2
[1] != 'b')
203 [StructLayout(LayoutKind
.Sequential
, Pack
= 1, CharSet
= CharSet
.Unicode
)]
204 public struct Struct1
206 [MarshalAs(UnmanagedType
.ByValTStr
, SizeConst
= 8)]
207 public string Field1
;
208 [MarshalAs(UnmanagedType
.ByValTStr
, SizeConst
= 10)]
209 public string Field2
;
210 [MarshalAs(UnmanagedType
.ByValTStr
, SizeConst
= 14)]
211 public string Field3
;
214 public static int test_0_byvaltstr () {
215 ByValTStrStruct s
= new ByValTStrStruct ();
217 IntPtr p2
= Marshal
.AllocHGlobal (Marshal
.SizeOf (typeof (ByValTStrStruct
)));
218 Marshal
.StructureToPtr(s
, p2
, false);
220 /* Check that the ByValTStr is initialized correctly */
221 for (int i
= 0; i
< 4; ++i
)
222 if (Marshal
.ReadByte (p2
, i
) != 0)
228 Marshal
.StructureToPtr(s
, p2
, false);
230 ByValTStrStruct s2
= (ByValTStrStruct
)Marshal
.PtrToStructure (p2
, typeof (ByValTStrStruct
));
232 /* The fourth char is lost because of null-termination */
239 // Check that decoding also respects the size, even when there is no null terminator
240 byte[] data
= Encoding
.ASCII
.GetBytes ("ABCDXXXX");
241 int size
= Marshal
.SizeOf (typeof (ByValTStrStruct
));
242 IntPtr buffer
= Marshal
.AllocHGlobal (size
);
243 Marshal
.Copy (data
, 0, buffer
, size
);
245 s2
= (ByValTStrStruct
)Marshal
.PtrToStructure (buffer
, typeof (ByValTStrStruct
));
252 public static int test_0_byvaltstr_unicode () {
253 ByValWStrStruct s
= new ByValWStrStruct ();
255 IntPtr p2
= Marshal
.AllocHGlobal (Marshal
.SizeOf (typeof (ByValWStrStruct
)));
256 Marshal
.StructureToPtr(s
, p2
, false);
258 /* Check that the ByValWStr is initialized correctly */
259 for (int i
= 0; i
< 8; ++i
)
260 if (Marshal
.ReadByte (p2
, i
) != 0)
266 Marshal
.StructureToPtr(s
, p2
, false);
268 ByValWStrStruct s2
= (ByValWStrStruct
)Marshal
.PtrToStructure (p2
, typeof (ByValWStrStruct
));
270 /* The fourth char is lost because of null-termination */
279 public static int test_0_byvaltstr_max_size () {
280 string buffer
= "12345678123456789012345678901234";
282 IntPtr ptr
= Marshal
.StringToBSTR (buffer
);
284 Struct1 data
= (Struct1
)Marshal
.PtrToStructure (ptr
, typeof (Struct1
));
285 if (data
.Field1
!= "12345678")
287 if (data
.Field2
!= "1234567890")
289 if (data
.Field3
!= "12345678901234")
294 // Check that the 'Pack' directive on a struct changes the min alignment of the struct as well (#12110)
295 public static int test_0_struct_pack () {
296 if (Marshal
.OffsetOf (typeof (PackStruct2
), "s") != new IntPtr (1))
301 public static int test_0_generic_ptr_to_struct () {
302 int size
= Marshal
.SizeOf (typeof (SimpleStruct2
));
303 IntPtr p
= Marshal
.AllocHGlobal (size
);
305 Marshal
.WriteInt32 (p
, 0, 1); //a
306 Marshal
.WriteInt32 (p
, 4, 2); //a
308 var s
= Marshal
.PtrToStructure
<SimpleStruct2
> (p
);
317 public static int test_0_invalid_array_throws () {
318 var ptr
= Marshal
.AllocHGlobal(Marshal
.SizeOf (typeof (InvalidArrayForMarshalingStruct
)));
320 Marshal
.PtrToStructure (ptr
, typeof (InvalidArrayForMarshalingStruct
));
322 catch (MarshalDirectiveException e
) {
328 public static int test_0_multidimentional_arrays () {
329 var structToMarshal
= new TwoDimensionalArrayStruct (new[, ] { {1, 2, 3}
, {4, 5, 6}
});
330 var ptr
= Marshal
.AllocHGlobal (Marshal
.SizeOf (structToMarshal
));
331 Marshal
.StructureToPtr (structToMarshal
, ptr
, false);
333 if(((int*)ptr
)[4] == 5)