Change Auto charset to mean UTF-8 off-Windows (#23664)
[platform/upstream/coreclr.git] / tests / src / Interop / StructMarshalling / PInvoke / MarshalStructAsParamDLL.h
1 #include <platformdefines.h>
2 #include <xplatform.h>
3
4 inline char* CoStrDup(const char* str)
5 {
6         size_t size = strlen(str) + 1;
7         char* dup = (char *)CoreClrAlloc(size);
8     if (dup != nullptr)
9     {
10         strcpy_s(dup, size, str);
11     }
12     return dup;
13 }
14
15 const int NumArrElements = 2;
16 struct InnerSequential
17 {
18         int f1;
19         float f2;
20         LPCSTR f3;
21 };
22 void PrintInnerSequential(InnerSequential* p, char const * name)
23 {
24         printf("\t%s.f1 = %d\n", name, p->f1);
25         printf("\t%s.f2 = %f\n", name, p->f2);
26         printf("\t%s.f3 = %s\n", name, p->f3);
27 }
28
29 void ChangeInnerSequential(InnerSequential* p)
30 {
31         p->f1 = 77;
32         p->f2 = 77.0;
33         p->f3 = CoStrDup("changed string");
34 }
35
36 bool IsCorrectInnerSequential(InnerSequential* p)
37 {
38         if(p->f1 != 1)
39                 return false;
40         if(p->f2 != 1.0)
41                 return false;
42         if(strcmp(p->f3, "") != 0)
43                 return false;
44
45         return true;
46 }
47
48 #ifndef WINDOWS
49 typedef int INT;
50 typedef unsigned int UINT;
51 typedef short SHORT;
52 typedef char CHAR;
53 typedef unsigned short WORD;
54 typedef short SHORT;
55 typedef float FLOAT;
56 typedef double DOUBLE;
57 #endif
58
59 struct INNER2 // size = 12 bytes
60 {
61     INT f1;
62     FLOAT f2;
63     LPCSTR f3;
64 };
65 void ChangeINNER2(INNER2* p)
66 {
67         p->f1 = 77;
68         p->f2 = 77.0;
69         p->f3 = CoStrDup("changed string");
70 }
71 void PrintINNER2(INNER2* p, char const * name)
72 {
73         printf("\t%s.f1 = %d\n", name, p->f1);
74         printf("\t%s.f2 = %f\n", name, p->f2);
75         printf("\t%s.f3 = %s\n", name, p->f3);
76 }
77 bool IsCorrectINNER2(INNER2* p)
78 {
79         if(p->f1 != 1)
80                 return false;
81         if(p->f2 != 1.0)
82                 return false;
83         if(memcmp(p->f3, "some string",11*sizeof(char)) != 0 )
84                 return false;
85         return true;
86 }
87
88
89 struct InnerExplicit 
90 {
91         #ifdef WINDOWS
92     union
93     {
94         INT f1;
95         FLOAT f2;
96     };
97         CHAR _unused0[4];
98     LPCSTR f3;
99         #endif 
100
101         #ifndef WINDOWS
102     union
103     {
104         INT f1;
105         FLOAT f2;
106     };
107         INT _unused0;
108     LPCSTR f3;
109         #endif 
110 };
111
112
113 void PrintInnerExplicit(InnerExplicit* p, char const * name)
114 {
115         printf("\t%s.f1 = %d\n", name, p->f1);
116         printf("\t%s.f2 = %f\n", name, p->f2);
117         printf("\t%s.f3 = %s\n", name, p->f3);
118 }
119
120 void ChangeInnerExplicit(InnerExplicit* p)
121 {
122         p->f1 = 77;
123         p->f3 = CoStrDup("changed string");
124 }
125
126 struct InnerArraySequential
127 {
128         InnerSequential arr[NumArrElements];
129 };
130
131 void PrintInnerArraySequential(InnerArraySequential* p, char const * name)
132 {
133         for(int i = 0; i < NumArrElements; i++)
134         {
135                 printf("\t%s.arr[%d].f1 = %d\n", name, i, (p->arr)[i].f1);
136                 printf("\t%s.arr[%d].f2 = %f\n", name, i, (p->arr)[i].f2);
137                 printf("\t%s.arr[%d].f3 = %s\n", name, i, (p->arr)[i].f3);
138         }
139 }
140
141 void ChangeInnerArraySequential(InnerArraySequential* p)
142 {
143         for(int i = 0; i < NumArrElements; i++)
144         {
145                 (p->arr)[i].f1 = 77;
146                 (p->arr)[i].f2 = 77.0;
147                 (p->arr)[i].f3 = CoStrDup("changed string");
148         }
149 }
150
151 bool IsCorrectInnerArraySequential(InnerArraySequential* p)
152 {
153         for(int i = 0; i < NumArrElements; i++)
154         {
155                 if( (p->arr)[i].f1 != 1 )
156                         return false;
157                 if( (p->arr)[i].f2 != 1.0 )
158                         return false;
159         }
160         return true;
161 }
162
163
164 union InnerArrayExplicit // size = 32 bytes
165 {
166         struct InnerSequential arr[2];
167         struct
168         {
169                 LONG64 _unused0;
170                 LPCSTR f4;
171         } s; 
172 };
173
174
175 #ifdef WINDOWS
176         #ifdef _WIN64
177         #pragma warning(push) 
178         #pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
179                 union OUTER3 // size = 32 bytes
180                 {
181                         struct InnerSequential arr[2];
182                         struct
183                         {
184                                 CHAR _unused0[24];
185                                 LPCSTR f4;
186                         };
187                 };
188         #pragma warning(pop)
189         #else
190                 struct OUTER3 // size = 28 bytes
191                 {
192                         struct InnerSequential arr[2];
193                         LPCSTR f4;
194                 };
195         #endif
196 #endif
197
198 #ifndef WINDOWS
199         struct OUTER3 // size = 28 bytes
200         {
201                 struct InnerSequential arr[2];
202                 LPCSTR f4;
203         };
204 #endif
205
206 void PrintOUTER3(OUTER3* p, char const * name)
207 {
208         for(int i = 0; i < NumArrElements; i++)
209         {
210                 printf("\t%s.arr[%d].f1 = %d\n", name, i, (p->arr)[i].f1);
211                 printf("\t%s.arr[%d].f2 = %f\n", name, i, (p->arr)[i].f2);
212                 printf("\t%s.arr[%d].f3 = %s\n", name, i, (p->arr)[i].f3);
213         }
214         printf("\t%s.f4 = %s\n",name,p->f4);
215 }
216 void ChangeOUTER3(OUTER3* p)
217 {
218         for(int i = 0; i < NumArrElements; i++)
219         {
220                 (p->arr)[i].f1 = 77;
221                 (p->arr)[i].f2 = 77.0;
222                 (p->arr)[i].f3 = CoStrDup("changed string");
223         }
224
225         p->f4 = CoStrDup("changed string");
226 }
227 bool IsCorrectOUTER3(OUTER3* p)
228 {
229         for(int i = 0; i < NumArrElements; i++)
230         {
231                 if( (p->arr)[i].f1 != 1 )
232                         return false;
233                 if( (p->arr)[i].f2 != 1.0 )
234                         return false;
235                 if( memcmp((p->arr)[i].f3, "some string",11*sizeof(char)) != 0 )
236                         return false;
237         }
238         if(memcmp(p->f4,"some string",11*sizeof(char)) != 0)
239         {
240                 return false;
241         }
242         return true;
243 }
244
245 struct CharSetAnsiSequential
246 {
247     LPCSTR f1;
248     char f2;
249 };
250
251 void PrintCharSetAnsiSequential(CharSetAnsiSequential* p, char const * name)
252 {
253         printf("\t%s.f1 = %s\n", name, p->f1);
254         printf("\t%s.f2 = %c\n", name, p->f2);
255 }
256
257 void ChangeCharSetAnsiSequential(CharSetAnsiSequential* p)
258 {
259         p->f1 = CoStrDup("change string");
260         p->f2 = 'n';
261 }
262
263 bool IsCorrectCharSetAnsiSequential(CharSetAnsiSequential* p)
264 {
265         if(strcmp((char*)p->f1, (char*)"some string") != 0 )
266                 return false;
267         if(p->f2 != 'c')
268                 return false;
269         return true;
270 }
271
272
273 struct CharSetUnicodeSequential 
274 {
275     LPCWSTR f1;
276     WCHAR f2;
277 };
278 void PrintCharSetUnicodeSequential(CharSetUnicodeSequential* p, char const * name)
279 {
280 #ifdef _WIN32
281         wprintf(L"\t%S.f1 = %s\n", name, p->f1);
282 #else
283         wprintf(L"\t%s.f1 = %S\n", name, p->f1);
284 #endif
285         printf("\t%s.f2 = %c\n", name, p->f2);
286 }
287
288 void ChangeCharSetUnicodeSequential(CharSetUnicodeSequential* p)
289 {
290 #ifdef _WIN32
291         LPCWSTR strSource = L"change string";
292 #else
293         LPCWSTR strSource = u"change string";
294 #endif
295         size_t len = TP_slen(strSource);
296         LPCWSTR temp = (LPCWSTR)CoreClrAlloc(sizeof(WCHAR)*(len+1));
297         if(temp != NULL)
298         {
299                 TP_scpy_s((WCHAR*)temp, (len+1), strSource);
300                 p->f1 = temp;
301                 p->f2 = L'n';
302         }
303         else
304         {
305                 printf("Memory Allocated Failed!");
306         }
307 }
308
309 bool IsCorrectCharSetUnicodeSequential(CharSetUnicodeSequential* p)
310 {
311 #ifdef _WIN32
312         LPCWSTR expected= L"some string";
313 #else
314         LPCWSTR expected= u"some string";
315 #endif
316         LPCWSTR actual = p->f1;
317         if(0 != TP_wcmp_s((WCHAR*)actual, (WCHAR*)expected))
318         {
319                 return false;
320         }
321         if(p->f2 != L'c')
322         {
323                 return false;
324         }
325         return true;
326 }
327
328
329 struct NumberSequential // size = 64 bytes
330 {
331         LONG64 i64;
332         ULONG64 ui64;
333         DOUBLE d;
334     INT i32;            
335     UINT ui32;          
336     SHORT s1;           
337     WORD us1;   
338         SHORT i16;              
339     WORD ui16;
340         FLOAT sgl;
341     BYTE b;                     
342     CHAR sb;              
343 };
344 void PrintNumberSequential(NumberSequential* str, char const * name)
345 {
346         printf("\t%s.i32 = %d\n", name, str->i32);
347         printf("\t%s.ui32 = %d\n", name, str->ui32);
348         printf("\t%s.s1 = %d\n", name, str->s1);
349         printf("\t%s.us1 = %u\n", name, str->us1);
350         printf("\t%s.b = %u\n", name, str->b);
351         printf("\t%s.sb = %d\n", name, str->sb);
352         printf("\t%s.i16 = %d\n", name, str->i16);
353         printf("\t%s.ui16 = %u\n", name, str->ui16);
354         printf("\t%s.i64 = %lld\n", name, str->i64);
355         printf("\t%s.ui64 = %llu\n", name, str->ui64);
356         printf("\t%s.sgl = %f\n", name, str->sgl);
357         printf("\t%s.d = %f\n",name, str->d);
358 }
359 void ChangeNumberSequential(NumberSequential* p)
360 {
361         p->i32 = 0;
362         p->ui32 = 32;
363         p->s1 = 0;
364         p->us1 = 16;
365         p->b = 0;
366         p->sb = 8;
367         p->i16 = 0;
368         p->ui16 = 16;
369         p->i64 = 0;
370         p->ui64 = 64;
371         p->sgl = 64.0;
372         p->d = 6.4;
373 }
374
375 bool IsCorrectNumberSequential(NumberSequential* p)
376 {
377         if(p->i32 != (-0x7fffffff - 1) || p->ui32 != 0xffffffff || p->s1 != -0x8000 || p->us1 != 0xffff || p->b != 0 ||
378                 p->sb != 0x7f ||p->i16 != -0x8000 || p->ui16 != 0xffff || p->i64 != -1234567890 ||
379                 p->ui64 != 1234567890 || (p->sgl) != 32.0 || p->d != 3.2)
380         {
381                 return false;
382         }
383         return true;
384 }
385
386 struct S3 // size = 1032 bytes
387 {
388     BOOL flag;
389     LPCSTR str;
390     INT vals[256];
391 };
392
393 void PrintS3(S3* str, char const * name)
394 {
395         printf("\t%s.flag = %d\n", name, str->flag);
396         printf("\t%s.str = %s\n", name, str->str);
397         for(int i = 0; i<256 ;i++)
398         {
399                 printf("\t%s.vals[%d] = %d\n",name,i,str->vals[i]);
400         }
401 }
402
403 void ChangeS3(S3* p)
404 {
405         p->flag = false;
406
407         /*CoreClrFree((void *)p->str);*/
408         p->str = CoStrDup("change string");
409
410     for(int i = 1;i<257;i++)
411         {
412                 p->vals[i-1] = i;
413         }
414 }
415
416 bool IsCorrectS3(S3* p)
417 {
418         int iflag = 0;
419
420         if (!p->flag || strcmp(p->str, "") != 0)
421                 return false;
422     for (int i = 0; i < 256; i++)
423     {
424         if (p->vals[i] != i)
425         {
426             printf("\tThe Index of %i is not expected",i);
427             iflag++;
428         }
429     }
430     if (iflag != 0)
431     {
432         return false;
433     }
434         return true;
435 }
436
437 struct S4 // size = 8 bytes
438 {
439     INT age;
440     LPCSTR name;
441 };
442 enum Enum1 
443 {
444     e1 = 1,
445     e2 = 3 
446 };
447 struct S5 // size = 8 bytes
448 {
449     struct S4 s4;
450     Enum1 ef;
451 };
452
453 void PrintS5(S5* str, char const * name)
454 {
455         printf("\t%s.s4.age = %d", name, str->s4.age);
456         printf("\t%s.s4.name = %s", name, str->s4.name);
457         printf("\t%s.ef = %d", name, str->ef);
458 }
459 void ChangeS5(S5* str)
460 {
461         str->s4.name = CoStrDup("change string");
462         str->s4.age = 64;
463         str->ef = e2;
464 }
465 bool IsCorrectS5(S5* str)
466 {
467         if(str->s4.age != 32 || strcmp(str->s4.name, "") != 0)
468                 return false;
469         if(str->ef != e1)
470                 return false;
471         return true;
472 }
473
474 struct StringStructSequentialAnsi // size = 8 bytes
475 {
476         LPCSTR first;
477     LPCSTR last;
478 };
479
480 void PrintStringStructSequentialAnsi(StringStructSequentialAnsi* str, char const * name)
481 {
482         printf("\t%s.first = %s\n", name, str->first);
483         printf("\t%s.last = %s\n", name, str->last);
484 }
485
486 bool IsCorrectStringStructSequentialAnsi(StringStructSequentialAnsi* str)
487 {
488         char strOne[512];
489         char strTwo[512];
490         for(int i = 0;i<512;i++)
491         {
492                 strOne[i] = 'a';
493                 strTwo[i] = 'b';
494         }
495
496         if(memcmp(str->first,strOne,512)!= 0)
497                 return false;
498
499         if(memcmp(str->last,strTwo,512)!= 0)
500                 return false;
501
502         return true;
503 }
504
505 void ChangeStringStructSequentialAnsi(StringStructSequentialAnsi* str)
506 {
507         char* newFirst = (char*)CoreClrAlloc(sizeof(char)*513);
508         char* newLast = (char*)CoreClrAlloc(sizeof(char)*513);
509         for (int i = 0; i < 512; ++i)
510         {
511                 newFirst[i] = 'b';
512                 newLast[i] = 'a';
513         }
514         newFirst[512] = '\0';
515         newLast[512] = '\0';
516
517         str->first = newFirst;  
518         str->last = newLast;
519 }
520
521 struct StringStructSequentialUnicode // size = 8 bytes
522 {
523     LPCWSTR first;
524     LPCWSTR last;
525 };
526
527 void PrintStringStructSequentialUnicode(StringStructSequentialUnicode* str, char const * name)
528 {
529 #ifdef _WIN32
530         wprintf(L"\t%S.first = %s\n", name, str->first);
531         wprintf(L"\t%S.last = %s\n", name, str->last);
532 #else
533         wprintf(L"\t%s.first = %s\n", name, str->first);
534         wprintf(L"\t%s.last = %s\n", name, str->last);
535 #endif
536 }
537
538 bool IsCorrectStringStructSequentialUnicode(StringStructSequentialUnicode* str)
539 {
540         WCHAR strOne[256+1];
541         WCHAR strTwo[256+1];
542
543         for(int i = 0;i<256;++i)
544         {
545                 strOne[i] = L'a';
546                 strTwo[i] = L'b';
547         }
548         strOne[256] = L'\0';
549         strTwo[256] = L'\0';
550
551         if(memcmp(str->first,strOne,256*sizeof(WCHAR)) != 0)
552                 return false;
553         if(memcmp(str->last,strTwo,256*sizeof(WCHAR)) != 0)
554                 return false;
555         return true;
556 }
557
558 void ChangeStringStructSequentialUnicode(StringStructSequentialUnicode* str)
559 {
560         WCHAR* newFirst = (WCHAR*)CoreClrAlloc(sizeof(WCHAR)*257);
561         WCHAR* newLast = (WCHAR*)CoreClrAlloc(sizeof(WCHAR)*257);
562         for (int i = 0; i < 256; ++i)
563         {
564                 newFirst[i] = L'b';
565                 newLast[i] = L'a';
566         }
567         newFirst[256] = L'\0';
568         newLast[256] = L'\0';
569         str->first = (const WCHAR*)newFirst;
570         str->last = (const WCHAR*)newLast;
571 }
572
573
574 struct S8 // size = 32 bytes
575 {
576     LPCSTR name;
577     BOOL gender;
578     INT i32;
579     UINT ui32;
580         WORD jobNum;
581     CHAR mySByte;
582 };
583 void PrintS8(S8* str, char const * name)
584 {
585         printf("\t%s.name = %s\n",name, str->name);
586         printf("\t%s.gender = %d\n", name, str->gender);
587         printf("\t%s.jobNum = %d\n",name, str->jobNum);
588         printf("\t%s.i32 = %d\n", name, str->i32);
589         printf("\t%s.ui32 = %u\n", name, str->ui32);
590         printf("\t%s.mySByte = %c\n", name, str->mySByte);
591 }
592 bool IsCorrectS8(S8* str)
593 {
594         if(memcmp( str->name,"hello", strlen("hello")*sizeof(char)+1 )!= 0)
595                 return false;
596         if(!str->gender)
597                 return false;
598         if(str->jobNum != 10)
599                 return false;
600         if(str->i32!= 128 || str->ui32 != 128)
601                 return false;
602         if(str->mySByte != 32)
603                 return false;
604         return true;
605 }
606
607 void ChangeS8(S8* str)
608 {
609         str->name = CoStrDup("world");
610         str->gender = false;
611         str->jobNum = 1;
612         str->i32 = 256;
613         str->ui32 = 256;
614         str->mySByte = 64;
615 }
616 #pragma pack (8)
617 struct S_int // size = 4 bytes
618 {
619     INT i;
620 };
621
622 struct S9;
623 typedef void (*TestDelegate1)(struct S9 myStruct);
624
625 struct S9 // size = 8 bytes
626 {
627     INT i32;
628     TestDelegate1 myDelegate1;
629 };
630
631 struct S101 // size = 8 bytes
632 {
633     INT i;
634     struct S_int s_int;
635 };
636
637 struct S10 // size = 8 bytes
638 {
639     struct S101 s;
640 };
641 void PrintS10(S10* str, char const * name)
642 {
643         printf("\t%s.s.s_int.i = %d\n", name, str->s.s_int.i);
644         printf("\t%s.s.i = %d\n", name, str->s.i);
645 }
646 bool IsCorrectS10(S10* str)
647 {
648         if(str->s.s_int.i != 32)
649                 return false;
650         if(str->s.i != 32)
651                 return false;
652         return true;
653 }
654 void ChangeS10(S10* str)
655 {
656         str->s.s_int.i = 64;
657         str->s.i = 64;
658 }
659
660 #ifndef WINDOWS
661 typedef int* LPINT;
662 #endif
663
664 struct S11 // size = 8 bytes
665 {
666     LPINT i32;
667     INT i;
668 };
669
670 union U // size = 8 bytes
671 {
672     INT i32;
673     UINT ui32;
674     LPVOID iPtr;
675     LPVOID uiPtr;
676     SHORT s;
677     WORD us;
678     BYTE b;
679     CHAR sb;
680     LONG64 l;
681     ULONG64 ul;
682     FLOAT f;
683     DOUBLE d;
684 };
685
686 void PrintU(U* str, char const * name)
687 {
688         printf("\t%s.i32 = %d\n", name, str->i32);
689         printf("\t%s.ui32 = %u\n", name, str->ui32);
690         printf("\t%s.iPtr = %p\n", name, str->iPtr);
691         printf("\t%s.uiPtr = %p\n", name, str->uiPtr);
692         printf("\t%s.s = %d\n", name, str->s);
693         printf("\t%s.us = %u\n", name, str->us);
694         printf("\t%s.b = %u\n", name, str->b);
695         printf("\t%s.sb = %d\n", name, str->sb);
696         printf("\t%s.l = %lld\n", name, str->l);
697         printf("\t%s.ul = %llu\n", name, str->ul);
698         printf("\t%s.f = %f\n", name, str->f);
699         printf("\t%s.d = %f\n", name, str->d);
700 }
701
702 void ChangeU(U* p)
703 {
704         p->i32 = 2147483647;
705         p->ui32 = 0;
706         p->iPtr = (LPVOID)(-64);
707         p->uiPtr = (LPVOID)(64);
708         p->s = 32767;
709         p->us = 0;
710         p->b = 255;
711         p->sb = -128;
712         p->l = -1234567890;
713         p->ul = 0;
714         p->f = 64.0;
715         p->d = 6.4;
716 }
717
718 bool IsCorrectU(U* p)
719 {
720         if(p->d != 3.2)
721         {
722                 return false;
723         }
724         return true;
725 }
726
727 struct ByteStructPack2Explicit // size = 2 bytes
728 {
729     BYTE b1;
730     BYTE b2;
731 };
732 void PrintByteStructPack2Explicit(ByteStructPack2Explicit* str, char const * name)
733 {
734         printf("\t%s.b1 = %d", name, str->b1);
735         printf("\t%s.b2 = %d", name, str->b2);
736 }
737
738 void ChangeByteStructPack2Explicit(ByteStructPack2Explicit* p)
739 {
740         p->b1 = 64;
741         p->b2 = 64;
742 }
743 bool IsCorrectByteStructPack2Explicit(ByteStructPack2Explicit* p)
744 {
745         if(p->b1 != 32 || p->b2 != 32)
746                 return false;
747         return true;
748 }
749
750
751
752 struct ShortStructPack4Explicit // size = 4 bytes
753 {
754     SHORT s1;
755     SHORT s2;
756 };
757
758 void PrintShortStructPack4Explicit(ShortStructPack4Explicit* str, char const * name)
759 {
760         printf("\t%s.s1 = %d", name, str->s1);
761         printf("\t%s.s2 = %d", name, str->s2);
762 }
763 void ChangeShortStructPack4Explicit(ShortStructPack4Explicit* p)
764 {
765         p->s1 = 64;
766         p->s2 = 64;
767 }
768 bool IsCorrectShortStructPack4Explicit(ShortStructPack4Explicit* p)
769 {
770         if(p->s1 != 32 || p->s2 != 32)
771                 return false;
772         return true;
773 }
774
775
776 struct IntStructPack8Explicit // size = 8 bytes
777 {
778     INT i1;
779     INT i2;
780 };
781
782 void PrintIntStructPack8Explicit(IntStructPack8Explicit* str, char const * name)
783 {
784         printf("\t%s.i1 = %d", name, str->i1);
785         printf("\t%s.i2 = %d", name, str->i2);
786 }
787 void ChangeIntStructPack8Explicit(IntStructPack8Explicit* p)
788 {
789         p->i1 = 64;
790         p->i2 = 64;
791 }
792 bool IsCorrectIntStructPack8Explicit(IntStructPack8Explicit* p)
793 {
794         if(p->i1 != 32 || p->i2 != 32)
795                 return false;
796         return true;
797 }
798
799 struct LongStructPack16Explicit // size = 16 bytes
800 {
801     LONG64 l1;
802     LONG64 l2;
803 };
804
805 void PrintLongStructPack16Explicit(LongStructPack16Explicit* str, char const * name)
806 {
807         printf("\t%s.l1 = %lld", name, str->l1);
808         printf("\t%s.l2 = %lld", name, str->l2);
809 }
810 void ChangeLongStructPack16Explicit(LongStructPack16Explicit* p)
811 {
812         p->l1 = 64;
813         p->l2 = 64;
814 }
815 bool IsCorrectLongStructPack16Explicit(LongStructPack16Explicit* p)
816 {
817         if(p->l1 != 32 || p->l2 != 32)
818                 return false;
819         return true;
820 }
821
822 struct AutoString
823 {
824 #ifdef _WIN32
825     LPCWSTR str;
826 #else
827     LPCSTR str;
828 #endif
829 };
830
831 struct HFA
832 {
833     float f1;
834     float f2;
835     float f3;
836     float f4;
837 };
838
839 struct ManyInts
840 {
841     int i1;
842     int i2;
843     int i3;
844     int i4;
845     int i5;
846     int i6;
847     int i7;
848     int i8;
849     int i9;
850     int i10;
851     int i11;
852     int i12;
853     int i13;
854     int i14;
855     int i15;
856     int i16;
857     int i17;
858     int i18;
859     int i19;
860     int i20;
861 };
862
863 struct MultipleBools
864 {
865     BOOL b1;
866     BOOL b2;
867 };
868
869 struct IntWithInnerSequential
870 {
871     int i1;
872     InnerSequential sequential;
873 };
874
875 struct SequentialWrapper
876 {
877     InnerSequential sequential;
878 };
879
880 struct SequentialDoubleWrapper
881 {
882     SequentialWrapper wrapper;
883 };
884
885 struct AggregateSequentialWrapper
886 {
887     SequentialWrapper wrapper1;
888     InnerSequential sequential;
889     SequentialWrapper wrapper2;
890 };