Add PInvoke/Array tests (#19266)
[platform/upstream/coreclr.git] / tests / src / Interop / PInvoke / Array / MarshalArrayAsParam / LPArrayNative / MarshalArrayLPArrayNative.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 #include <xplatform.h>
6 #include "MarshalArray.h"
7
8 template<typename T>
9 bool Equals(T *pActual, int cActual, T *pExpected, int cExpected)
10 {
11     if (pActual == NULL && pExpected == NULL)
12         return true;
13     else if (pActual == NULL && pExpected != NULL)
14         return false;
15     else if (pActual != NULL && pExpected == NULL)
16         return false;
17     else if (cActual != cExpected)
18         return false;
19
20     for (int i = 0; i < cExpected; ++i)
21     {
22         if (!IsObjectEquals(pActual[i], pExpected[i]))
23         {
24             printf("WARNING: Test error - %s\n", __FUNCSIG__);
25             return false;
26         }
27     }
28
29     return true;
30 }
31
32 #define EQUALS(__actual, __cActual, __expected) Equals((__actual), (__cActual), (__expected), (int)sizeof(__expected) / sizeof(__expected[0]))
33 #define INIT_EXPECTED(__type, __size)   \
34     __type expected[(__size)]; \
35 for (size_t i = 0; i < (__size); ++i) \
36     expected[i] = (__type)i
37
38 /////////////////////////////////////////// By Value /////////////////////////////////////////
39 extern "C" DLL_EXPORT BOOL CStyle_Array_Int(int *pActual, int cActual)
40 {
41     CHECK_PARAM_NOT_EMPTY(pActual);
42
43     INIT_EXPECTED(int, ARRAY_SIZE);
44
45     return EQUALS(pActual, cActual, expected);
46 }
47
48 #ifdef _WIN32
49 extern "C" DLL_EXPORT BOOL CStyle_Array_Object(VARIANT *pActual, int cActual)
50 {
51     CHECK_PARAM_NOT_EMPTY(pActual);
52
53     //VARIANT expected[ARRAY_SIZE];
54     size_t nullIdx = ARRAY_SIZE / 2;
55
56     for (size_t i = 0; i < ARRAY_SIZE; ++i)
57     {
58         //VariantInit(&expected[i]);
59         if (i == nullIdx)
60         {
61             if ((pActual[i].vt != VT_EMPTY))
62             {
63                 printf("=====EMPTY VALUE NOT FOUND==== %s\n", __FUNCTION__);
64                 return FALSE;
65             }
66             else
67             {
68                 continue;
69             }
70         }
71         if ((pActual[i].vt != VT_I4) && ((size_t)(pActual[i].lVal) != i))
72         {
73             printf("====VARIANTS NOT EQUAL==== %s\n", __FUNCTION__);
74             return TRUE;
75         }
76     }
77
78     return TRUE;
79     //EQUALS(pActual, cActual, expected);
80 }
81 #endif
82
83 extern "C" DLL_EXPORT BOOL CStyle_Array_Uint(UINT *pActual, int cActual)
84 {
85     CHECK_PARAM_NOT_EMPTY(pActual);
86
87     INIT_EXPECTED(UINT, ARRAY_SIZE);
88
89     return EQUALS(pActual, cActual, expected);
90 }
91
92 extern "C" DLL_EXPORT BOOL CStyle_Array_Short(SHORT *pActual, int cActual)
93 {
94     CHECK_PARAM_NOT_EMPTY(pActual);
95
96     INIT_EXPECTED(SHORT, ARRAY_SIZE);
97
98     return EQUALS(pActual, cActual, expected);
99 }
100
101 extern "C" DLL_EXPORT BOOL CStyle_Array_Word(WORD *pActual, int cActual)
102 {
103     CHECK_PARAM_NOT_EMPTY(pActual);
104
105     INIT_EXPECTED(WORD, ARRAY_SIZE);
106
107     return EQUALS(pActual, cActual, expected);
108 }
109
110 extern "C" DLL_EXPORT BOOL CStyle_Array_Long64(LONG64 *pActual, int cActual)
111 {
112     CHECK_PARAM_NOT_EMPTY(pActual);
113
114     INIT_EXPECTED(LONG64, ARRAY_SIZE);
115
116     return EQUALS(pActual, cActual, expected);
117 }
118
119 extern "C" DLL_EXPORT BOOL CStyle_Array_ULong64(ULONG64 *pActual, int cActual)
120 {
121     CHECK_PARAM_NOT_EMPTY(pActual);
122
123     INIT_EXPECTED(ULONG64, ARRAY_SIZE);
124
125     return EQUALS(pActual, cActual, expected);
126 }
127
128 extern "C" DLL_EXPORT BOOL CStyle_Array_Double(DOUBLE *pActual, int cActual)
129 {
130     CHECK_PARAM_NOT_EMPTY(pActual);
131
132     INIT_EXPECTED(DOUBLE, ARRAY_SIZE);
133
134     return EQUALS(pActual, cActual, expected);
135 }
136
137 extern "C" DLL_EXPORT BOOL CStyle_Array_Float(FLOAT *pActual, int cActual)
138 {
139     CHECK_PARAM_NOT_EMPTY(pActual);
140
141     INIT_EXPECTED(FLOAT, ARRAY_SIZE);
142
143     return EQUALS(pActual, cActual, expected);
144 }
145
146 extern "C" DLL_EXPORT BOOL CStyle_Array_Byte(BYTE *pActual, int cActual)
147 {
148     CHECK_PARAM_NOT_EMPTY(pActual);
149
150     INIT_EXPECTED(BYTE, ARRAY_SIZE);
151
152     return EQUALS(pActual, cActual, expected);
153 }
154
155 extern "C" DLL_EXPORT BOOL CStyle_Array_Char(CHAR *pActual, int cActual)
156 {
157     CHECK_PARAM_NOT_EMPTY(pActual);
158
159     INIT_EXPECTED(CHAR, ARRAY_SIZE);
160
161     return EQUALS(pActual, cActual, expected);
162 }
163
164 extern "C" DLL_EXPORT BOOL CStyle_Array_LPCSTR(LPCSTR *pActual, int cActual)
165 {
166     CHECK_PARAM_NOT_EMPTY(pActual);
167
168     LPSTR expected[ARRAY_SIZE];
169     size_t nullIdx = ARRAY_SIZE / 2;
170     for (size_t i = 0; i < ARRAY_SIZE; ++i)
171     {
172         if (i == nullIdx)
173         {
174             expected[i] = NULL;
175             continue;
176         }
177         expected[i] = ToString((int)i);
178     }
179
180     int retval = EQUALS((LPSTR *)pActual, cActual, expected);
181
182     for (size_t i = 0; i < ARRAY_SIZE; ++i)
183     {
184         if (i == nullIdx)
185             continue;
186
187         CoreClrFree(expected[i]);
188     }
189
190     return retval;
191 }
192
193 extern "C" DLL_EXPORT BOOL CStyle_Array_LPSTR(LPSTR *pActual, int cActual)
194 {
195     CHECK_PARAM_NOT_EMPTY(pActual);
196
197     return CStyle_Array_LPCSTR((LPCSTR *)pActual, cActual);
198 }
199
200 extern "C" DLL_EXPORT BOOL CStyle_Array_Struct(TestStruct *pActual, int cActual)
201 {
202     CHECK_PARAM_NOT_EMPTY(pActual);
203
204     TestStruct expected[ARRAY_SIZE];
205     for (size_t i = 0; i < ARRAY_SIZE; ++i)
206     {
207         expected[i].x = (int)i;
208         expected[i].d = (int)i;
209         expected[i].l = (LONG64)i;
210         expected[i].str = ToString((int)i);
211     }
212
213     return EQUALS(pActual, cActual, expected);
214 }
215
216 extern "C" DLL_EXPORT BOOL CStyle_Array_Bool(BOOL *pActual, int cActual)
217 {
218     CHECK_PARAM_NOT_EMPTY(pActual);
219
220     BOOL expected[ARRAY_SIZE];
221     for (size_t i = 0; i < ARRAY_SIZE; ++i)
222     {
223         if (i % 2 == 0)
224             expected[i] = TRUE;
225         else
226             expected[i] = FALSE;
227     }
228
229     return EQUALS(pActual, cActual, expected);
230 }
231
232 /////////////////////////////////////////// In Out By Value /////////////////////////////////////////
233 template<typename T>
234 void ChangeArrayValue(T *pArray, int cSize)
235 {
236     for (int i = 0; i < cSize; ++i)
237         pArray[i] = (T)(cSize - 1 - i);
238 }
239
240 template<>
241 void ChangeArrayValue(LPSTR *pArray, int cSize)
242 {
243     for (int i = 0; i < cSize; ++i)
244     {
245         // Free resource
246         CoreClrFree(pArray[i]);
247         pArray[i] = ToString(cSize - 1 - i);
248     }
249
250     int nullIdx = cSize / 2 - 1;
251     CoreClrFree(pArray[nullIdx]);
252     pArray[nullIdx] = NULL;
253 }
254
255 template<>
256 void ChangeArrayValue(LPCSTR *pArray, int cSize)
257 {
258     for (int i = 0; i < cSize; ++i)
259     {
260         // Free resource
261         CoreClrFree((LPVOID)pArray[i]);
262         pArray[i] = ToString(cSize - 1 - i);
263     }
264
265     int nullIdx = cSize / 2 - 1;
266     CoreClrFree((LPVOID)pArray[nullIdx]);
267     pArray[nullIdx] = NULL;
268 }
269
270 #ifdef _WIN32
271 template<>
272 void ChangeArrayValue(VARIANT *pArray, int cSize)
273 {
274     for (int i = 0; i < cSize; ++i)
275     {
276         // Free resource
277         VariantClear(&pArray[i]);
278         pArray[i].vt = VT_I4;
279         pArray[i].lVal = cSize - 1 - i;
280     }
281
282     int nullIdx = cSize / 2 - 1;
283     VariantClear(&pArray[nullIdx]);
284     pArray[nullIdx].vt = VT_EMPTY;
285 }
286 #endif
287
288 template<>
289 void ChangeArrayValue(TestStruct *pArray, int cSize)
290 {
291     for (int i = 0; i < cSize; ++i)
292     {
293         int v = (cSize - 1 - i);
294         pArray[i].x = v;
295         pArray[i].d = v;
296         pArray[i].l = v;
297         pArray[i].str = ToString(v);
298     }
299 }
300
301 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_InOut(int *pActual, int cActual)
302 {
303         CHECK_PARAM_NOT_EMPTY(pActual);
304
305         BOOL retval = CStyle_Array_Int(pActual, cActual);
306         ChangeArrayValue(pActual, cActual);
307
308         return retval;
309 }
310
311 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_InOut_Null(int *pActual)
312 {
313         CHECK_PARAM_EMPTY(pActual);
314     return true;
315 }
316
317 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_InOut_ZeroLength(int *pActual)
318 {
319         CHECK_PARAM_NOT_EMPTY(pActual);
320         return true;
321 }
322
323 #ifdef _WIN32
324 extern "C" DLL_EXPORT BOOL CStyle_Array_Object_InOut(VARIANT *pActual, int cActual)
325 {
326     CHECK_PARAM_NOT_EMPTY(pActual);
327
328     BOOL retval = CStyle_Array_Object(pActual, cActual);
329     ChangeArrayValue(pActual, cActual);
330
331     return retval;
332 }
333 #endif
334
335 extern "C" DLL_EXPORT BOOL CStyle_Array_Uint_InOut(UINT *pActual, int cActual)
336 {
337     CHECK_PARAM_NOT_EMPTY(pActual);
338
339     BOOL retval = CStyle_Array_Uint(pActual, cActual);
340     ChangeArrayValue(pActual, cActual);
341
342     return retval;
343 }
344
345 extern "C" DLL_EXPORT BOOL CStyle_Array_Short_InOut(SHORT *pActual, int cActual)
346 {
347     CHECK_PARAM_NOT_EMPTY(pActual);
348
349     BOOL retval = CStyle_Array_Short(pActual, cActual);
350     ChangeArrayValue(pActual, cActual);
351
352     return retval;
353 }
354
355 extern "C" DLL_EXPORT BOOL CStyle_Array_Word_InOut(WORD *pActual, int cActual)
356 {
357     CHECK_PARAM_NOT_EMPTY(pActual);
358
359     BOOL retval = CStyle_Array_Word(pActual, cActual);
360     ChangeArrayValue(pActual, cActual);
361
362     return retval;
363 }
364
365 extern "C" DLL_EXPORT BOOL CStyle_Array_Long64_InOut(LONG64 *pActual, int cActual)
366 {
367     CHECK_PARAM_NOT_EMPTY(pActual);
368
369     BOOL retval = CStyle_Array_Long64(pActual, cActual);
370     ChangeArrayValue(pActual, cActual);
371
372     return retval;
373 }
374
375 extern "C" DLL_EXPORT BOOL CStyle_Array_ULong64_InOut(ULONG64 *pActual, int cActual)
376 {
377     CHECK_PARAM_NOT_EMPTY(pActual);
378
379     BOOL retval = CStyle_Array_ULong64(pActual, cActual);
380     ChangeArrayValue(pActual, cActual);
381
382     return retval;
383 }
384
385 extern "C" DLL_EXPORT BOOL CStyle_Array_Double_InOut(DOUBLE *pActual, int cActual)
386 {
387     CHECK_PARAM_NOT_EMPTY(pActual);
388
389     BOOL retval = CStyle_Array_Double(pActual, cActual);
390     ChangeArrayValue(pActual, cActual);
391
392     return retval;
393 }
394
395 extern "C" DLL_EXPORT BOOL CStyle_Array_Float_InOut(FLOAT *pActual, int cActual)
396 {
397     CHECK_PARAM_NOT_EMPTY(pActual);
398
399     BOOL retval = CStyle_Array_Float(pActual, cActual);
400     ChangeArrayValue(pActual, cActual);
401
402     return retval;
403 }
404
405 extern "C" DLL_EXPORT BOOL CStyle_Array_Byte_InOut(BYTE *pActual, int cActual)
406 {
407     CHECK_PARAM_NOT_EMPTY(pActual);
408
409     BOOL retval = CStyle_Array_Byte(pActual, cActual);
410     ChangeArrayValue(pActual, cActual);
411
412     return retval;
413 }
414
415 extern "C" DLL_EXPORT BOOL CStyle_Array_Char_InOut(CHAR *pActual, int cActual)
416 {
417     CHECK_PARAM_NOT_EMPTY(pActual);
418
419     BOOL retval = CStyle_Array_Char(pActual, cActual);
420     ChangeArrayValue(pActual, cActual);
421
422     return retval;
423 }
424
425 extern "C" DLL_EXPORT BOOL CStyle_Array_LPSTR_InOut(LPSTR *pActual, int cActual)
426 {
427     CHECK_PARAM_NOT_EMPTY(pActual);
428
429     BOOL retval = CStyle_Array_LPSTR(pActual, cActual);
430     ChangeArrayValue(pActual, cActual);
431
432     return retval;
433 }
434
435 extern "C" DLL_EXPORT BOOL CStyle_Array_Struct_InOut(TestStruct *pActual, int cActual)
436 {
437     CHECK_PARAM_NOT_EMPTY(pActual);
438
439     BOOL retval = CStyle_Array_Struct(pActual, cActual);
440     ChangeArrayValue(pActual, cActual);
441
442     return retval;
443 }
444
445 extern "C" DLL_EXPORT BOOL CStyle_Array_Bool_InOut(BOOL *pActual, int cActual)
446 {
447     CHECK_PARAM_NOT_EMPTY(pActual);
448
449     BOOL retval = CStyle_Array_Bool(pActual, cActual);
450
451     for (int i = 0; i < cActual; ++i)
452     {
453         if (i % 2 != 0)
454             pActual[i] = TRUE;
455         else
456             pActual[i] = FALSE;
457     }
458
459     return retval;
460 }
461
462 /////////////////////////////////////////// Out By Value /////////////////////////////////////////
463 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_Out(int *pActual, int cActual)
464 {
465         CHECK_PARAM_NOT_EMPTY(pActual);
466
467         ChangeArrayValue(pActual, cActual);
468
469     return true;
470 }
471 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_Out_Null(int *pActual)
472 {
473         CHECK_PARAM_EMPTY(pActual);
474         return true;
475 }
476
477 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_Out_ZeroLength(int *pActual)
478 {
479         CHECK_PARAM_NOT_EMPTY(pActual);
480         return true;
481 }
482
483 #ifdef _WIN32
484 extern "C" DLL_EXPORT BOOL CStyle_Array_Object_Out(VARIANT *pActual, int cActual)
485 {
486     CHECK_PARAM_NOT_EMPTY(pActual);
487
488     ChangeArrayValue(pActual, cActual);
489
490     return true;
491 }
492 #endif
493
494 extern "C" DLL_EXPORT BOOL CStyle_Array_Uint_Out(UINT *pActual, int cActual)
495 {
496     CHECK_PARAM_NOT_EMPTY(pActual);
497
498     ChangeArrayValue(pActual, cActual);
499
500     return true;
501 }
502
503 extern "C" DLL_EXPORT BOOL CStyle_Array_Short_Out(SHORT *pActual, int cActual)
504 {
505     CHECK_PARAM_NOT_EMPTY(pActual);
506
507     ChangeArrayValue(pActual, cActual);
508
509     return true;
510 }
511
512 extern "C" DLL_EXPORT BOOL CStyle_Array_Word_Out(WORD *pActual, int cActual)
513 {
514     CHECK_PARAM_NOT_EMPTY(pActual);
515
516     ChangeArrayValue(pActual, cActual);
517
518     return true;
519 }
520
521 extern "C" DLL_EXPORT BOOL CStyle_Array_Long64_Out(LONG64 *pActual, int cActual)
522 {
523     CHECK_PARAM_NOT_EMPTY(pActual);
524
525     ChangeArrayValue(pActual, cActual);
526
527     return true;
528 }
529
530 extern "C" DLL_EXPORT BOOL CStyle_Array_ULong64_Out(ULONG64 *pActual, int cActual)
531 {
532     CHECK_PARAM_NOT_EMPTY(pActual);
533
534     ChangeArrayValue(pActual, cActual);
535
536     return true;
537 }
538
539 extern "C" DLL_EXPORT BOOL CStyle_Array_Double_Out(DOUBLE *pActual, int cActual)
540 {
541     CHECK_PARAM_NOT_EMPTY(pActual);
542
543     ChangeArrayValue(pActual, cActual);
544
545     return true;
546 }
547
548 extern "C" DLL_EXPORT BOOL CStyle_Array_Float_Out(FLOAT *pActual, int cActual)
549 {
550     CHECK_PARAM_NOT_EMPTY(pActual);
551
552     ChangeArrayValue(pActual, cActual);
553
554     return true;
555 }
556
557 extern "C" DLL_EXPORT BOOL CStyle_Array_Byte_Out(BYTE *pActual, int cActual)
558 {
559     CHECK_PARAM_NOT_EMPTY(pActual);
560
561     ChangeArrayValue(pActual, cActual);
562
563     return true;
564 }
565
566 extern "C" DLL_EXPORT BOOL CStyle_Array_Char_Out(CHAR *pActual, int cActual)
567 {
568     CHECK_PARAM_NOT_EMPTY(pActual);
569
570     ChangeArrayValue(pActual, cActual);
571
572     return true;
573 }
574
575 extern "C" DLL_EXPORT BOOL CStyle_Array_LPSTR_Out(LPSTR *pActual, int cActual)
576 {
577     CHECK_PARAM_NOT_EMPTY(pActual);
578
579     ChangeArrayValue(pActual, cActual);
580
581     return true;
582 }
583
584 extern "C" DLL_EXPORT BOOL CStyle_Array_Struct_Out(TestStruct *pActual, int cActual)
585 {
586     CHECK_PARAM_NOT_EMPTY(pActual);
587
588     ChangeArrayValue(pActual, cActual);
589
590     return true;
591 }
592
593 extern "C" DLL_EXPORT BOOL CStyle_Array_Bool_Out(BOOL *pActual, int cActual)
594 {
595     CHECK_PARAM_NOT_EMPTY(pActual);
596
597     for (int i = 0; i < cActual; ++i)
598     {
599         if (i % 2 != 0)
600             pActual[i] = TRUE;
601         else
602             pActual[i] = FALSE;
603     }
604
605     return true;
606 }
607
608 /////////////////////////////////////////// InAttribute ByRef /////////////////////////////////////////
609 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_In_Ref(int **ppActual, int cActual)
610 {
611     if (!CStyle_Array_Int(*ppActual, cActual))
612     {
613         return false;
614     }
615     ChangeArrayValue(*ppActual, cActual);
616     return true;
617 }
618
619 #ifdef _WIN32
620 extern "C" DLL_EXPORT BOOL CStyle_Array_Object_In_Ref(VARIANT **ppActual, int cActual)
621 {
622     if (!CStyle_Array_Object(*ppActual, cActual))
623         return false;
624
625     ChangeArrayValue(*ppActual, cActual);
626     return true;
627 }
628 #endif
629
630 extern "C" DLL_EXPORT BOOL CStyle_Array_Uint_In_Ref(UINT **ppActual, int cActual)
631 {
632     if (!CStyle_Array_Uint(*ppActual, cActual))
633         return false;
634
635     ChangeArrayValue(*ppActual, cActual);
636     return true;
637 }
638
639 extern "C" DLL_EXPORT BOOL CStyle_Array_Short_In_Ref(SHORT **ppActual, int cActual)
640 {
641     if (!CStyle_Array_Short(*ppActual, cActual))
642         return false;
643
644     ChangeArrayValue(*ppActual, cActual);
645     return true;
646 }
647
648 extern "C" DLL_EXPORT BOOL CStyle_Array_Word_In_Ref(WORD **ppActual, int cActual)
649 {
650     if (!CStyle_Array_Word(*ppActual, cActual))
651         return false;
652
653     ChangeArrayValue(*ppActual, cActual);
654     return true;
655 }
656
657 extern "C" DLL_EXPORT BOOL CStyle_Array_Long64_In_Ref(LONG64 **ppActual, int cActual)
658 {
659     if (!CStyle_Array_Long64(*ppActual, cActual))
660         return false;
661
662     ChangeArrayValue(*ppActual, cActual);
663     return true;
664 }
665
666 extern "C" DLL_EXPORT BOOL CStyle_Array_ULong64_In_Ref(ULONG64 **ppActual, int cActual)
667 {
668     if (!CStyle_Array_ULong64(*ppActual, cActual))
669         return false;
670
671     ChangeArrayValue(*ppActual, cActual);
672     return true;
673 }
674
675 extern "C" DLL_EXPORT BOOL CStyle_Array_Double_In_Ref(DOUBLE **ppActual, int cActual)
676 {
677     if (!CStyle_Array_Double(*ppActual, cActual))
678         return false;
679
680     ChangeArrayValue(*ppActual, cActual);
681     return true;
682 }
683
684 extern "C" DLL_EXPORT BOOL CStyle_Array_Float_In_Ref(FLOAT **ppActual, int cActual)
685 {
686     if (!CStyle_Array_Float(*ppActual, cActual))
687         return false;
688
689     ChangeArrayValue(*ppActual, cActual);
690     return true;
691 }
692
693 extern "C" DLL_EXPORT BOOL CStyle_Array_Byte_In_Ref(BYTE **ppActual, int cActual)
694 {
695     if (!CStyle_Array_Byte(*ppActual, cActual))
696         return false;
697
698     ChangeArrayValue(*ppActual, cActual);
699     return true;
700 }
701
702 extern "C" DLL_EXPORT BOOL CStyle_Array_Char_In_Ref(CHAR **ppActual, int cActual)
703 {
704     if (!CStyle_Array_Char(*ppActual, cActual))
705         return false;
706
707     ChangeArrayValue(*ppActual, cActual);
708     return true;
709 }
710
711 extern "C" DLL_EXPORT BOOL CStyle_Array_LPCSTR_In_Ref(LPCSTR **ppActual, int cActual)
712 {
713     if (!CStyle_Array_LPCSTR(*ppActual, cActual))
714         return false;
715
716     ChangeArrayValue(*ppActual, cActual);
717     return true;
718 }
719
720 extern "C" DLL_EXPORT BOOL CStyle_Array_LPSTR_In_Ref(LPSTR **ppActual, int cActual)
721 {
722     if (!CStyle_Array_LPSTR(*ppActual, cActual))
723         return false;
724
725     ChangeArrayValue(*ppActual, cActual);
726     return true;
727 }
728
729 extern "C" DLL_EXPORT BOOL CStyle_Array_Struct_In_Ref(TestStruct **ppActual, int cActual)
730 {
731     if (!CStyle_Array_Struct(*ppActual, cActual))
732         return false;
733
734     ChangeArrayValue(*ppActual, cActual);
735     return true;
736 }
737
738 extern "C" DLL_EXPORT BOOL CStyle_Array_Bool_In_Ref(BOOL **ppActual, int cActual)
739 {
740     if (!CStyle_Array_Bool(*ppActual, cActual))
741         return false;
742
743     BOOL *pActual = *ppActual;
744
745     for (int i = 0; i < cActual; ++i)
746     {
747         if (i % 2 != 0)
748             pActual[i] = TRUE;
749         else
750             pActual[i] = FALSE;
751     }
752
753     return true;
754 }
755
756 /////////////////////////////////////////// OutAttribute ByRef /////////////////////////////////////////
757 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_Out_Ref(int **ppActual, int cActual)
758 {
759     CHECK_PARAM_EMPTY(*ppActual);
760
761     ChangeArrayValue(*ppActual, cActual);
762
763     return true;
764 }
765
766 #ifdef _WIN32
767 extern "C" DLL_EXPORT BOOL CStyle_Array_Object_Out_Ref(VARIANT **ppActual, int cActual)
768 {
769     CHECK_PARAM_EMPTY(*ppActual);
770
771     ChangeArrayValue(*ppActual, cActual);
772
773     return true;
774 }
775 #endif
776
777 extern "C" DLL_EXPORT BOOL CStyle_Array_Uint_Out_Ref(UINT **ppActual, int cActual)
778 {
779     CHECK_PARAM_EMPTY(*ppActual);
780
781     ChangeArrayValue(*ppActual, cActual);
782
783     return true;
784 }
785
786 extern "C" DLL_EXPORT BOOL CStyle_Array_Short_Out_Ref(SHORT **ppActual, int cActual)
787 {
788     CHECK_PARAM_EMPTY(*ppActual);
789
790     ChangeArrayValue(*ppActual, cActual);
791
792     return true;
793 }
794
795 extern "C" DLL_EXPORT BOOL CStyle_Array_Word_Out_Ref(WORD **ppActual, int cActual)
796 {
797     CHECK_PARAM_EMPTY(*ppActual);
798
799     ChangeArrayValue(*ppActual, cActual);
800
801     return true;
802 }
803
804 extern "C" DLL_EXPORT BOOL CStyle_Array_Long64_Out_Ref(LONG64 **ppActual, int cActual)
805 {
806     CHECK_PARAM_EMPTY(*ppActual);
807
808     ChangeArrayValue(*ppActual, cActual);
809
810     return true;
811 }
812
813 extern "C" DLL_EXPORT BOOL CStyle_Array_ULong64_Out_Ref(ULONG64 **ppActual, int cActual)
814 {
815     CHECK_PARAM_EMPTY(*ppActual);
816
817     ChangeArrayValue(*ppActual, cActual);
818
819     return true;
820 }
821
822 extern "C" DLL_EXPORT BOOL CStyle_Array_Double_Out_Ref(DOUBLE **ppActual, int cActual)
823 {
824     CHECK_PARAM_EMPTY(*ppActual);
825
826     ChangeArrayValue(*ppActual, cActual);
827
828     return true;
829 }
830
831 extern "C" DLL_EXPORT BOOL CStyle_Array_Float_Out_Ref(FLOAT **ppActual, int cActual)
832 {
833     CHECK_PARAM_EMPTY(*ppActual);
834
835     ChangeArrayValue(*ppActual, cActual);
836
837     return true;
838 }
839
840 extern "C" DLL_EXPORT BOOL CStyle_Array_Byte_Out_Ref(BYTE **ppActual, int cActual)
841 {
842     CHECK_PARAM_EMPTY(*ppActual);
843
844     ChangeArrayValue(*ppActual, cActual);
845
846     return true;
847 }
848
849 extern "C" DLL_EXPORT BOOL CStyle_Array_Char_Out_Ref(CHAR **ppActual, int cActual)
850 {
851     CHECK_PARAM_EMPTY(*ppActual);
852
853     ChangeArrayValue(*ppActual, cActual);
854
855     return true;
856 }
857
858 extern "C" DLL_EXPORT BOOL CStyle_Array_LPCSTR_Out_Ref(LPCSTR **ppActual, int cActual)
859 {
860     CHECK_PARAM_EMPTY(*ppActual);
861
862     ChangeArrayValue(*ppActual, cActual);
863
864     return true;
865 }
866
867 extern "C" DLL_EXPORT BOOL CStyle_Array_LPSTR_Out_Ref(LPSTR **ppActual, int cActual)
868 {
869     CHECK_PARAM_EMPTY(*ppActual);
870
871     ChangeArrayValue(*ppActual, cActual);
872
873     return true;
874 }
875
876 extern "C" DLL_EXPORT BOOL CStyle_Array_Struct_Out_Ref(TestStruct **ppActual, int cActual)
877 {
878     CHECK_PARAM_EMPTY(*ppActual);
879
880     ChangeArrayValue(*ppActual, cActual);
881
882     return true;
883 }
884
885 extern "C" DLL_EXPORT BOOL CStyle_Array_Bool_Out_Ref(BOOL **ppActual, int cActual)
886 {
887     CHECK_PARAM_EMPTY(*ppActual);
888
889     BOOL *pArray = *ppActual;
890     for (int i = 0; i < cActual; ++i)
891     {
892         if (i % 2 != 0)
893             pArray[i] = TRUE;
894         else
895             pArray[i] = FALSE;
896     }
897
898     return true;
899 }
900
901 /////////////////////////////////////////// InAttribute OutAttribute ByRef /////////////////////////////////////////
902 extern "C" DLL_EXPORT BOOL CStyle_Array_Int_InOut_Ref(int **ppActual, int cActual)
903 {
904     CHECK_PARAM_NOT_EMPTY(*ppActual);
905
906     BOOL retval = CStyle_Array_Int_In_Ref(ppActual, cActual);
907     ChangeArrayValue(*ppActual, cActual);
908
909     return retval;
910 }
911
912 #ifdef _WIN32
913 extern "C" DLL_EXPORT BOOL CStyle_Array_Object_InOut_Ref(VARIANT **ppActual, int cActual)
914 {
915     CHECK_PARAM_NOT_EMPTY(*ppActual);
916
917     BOOL retval = CStyle_Array_Object_In_Ref(ppActual, cActual);
918     ChangeArrayValue(*ppActual, cActual);
919
920     return retval;
921 }
922 #endif
923
924 extern "C" DLL_EXPORT BOOL CStyle_Array_Uint_InOut_Ref(UINT **ppActual, int cActual)
925 {
926     CHECK_PARAM_NOT_EMPTY(*ppActual);
927
928     BOOL retval = CStyle_Array_Uint_In_Ref(ppActual, cActual);
929     ChangeArrayValue(*ppActual, cActual);
930
931     return retval;
932 }
933
934 extern "C" DLL_EXPORT BOOL CStyle_Array_Short_InOut_Ref(SHORT **ppActual, int cActual)
935 {
936     CHECK_PARAM_NOT_EMPTY(*ppActual);
937
938     BOOL retval = CStyle_Array_Short_In_Ref(ppActual, cActual);
939     ChangeArrayValue(*ppActual, cActual);
940
941     return retval;
942 }
943
944 extern "C" DLL_EXPORT BOOL CStyle_Array_Word_InOut_Ref(WORD **ppActual, int cActual)
945 {
946     CHECK_PARAM_NOT_EMPTY(*ppActual);
947
948     BOOL retval = CStyle_Array_Word_In_Ref(ppActual, cActual);
949     ChangeArrayValue(*ppActual, cActual);
950
951     return retval;
952 }
953
954 extern "C" DLL_EXPORT BOOL CStyle_Array_Long64_InOut_Ref(LONG64 **ppActual, int cActual)
955 {
956     CHECK_PARAM_NOT_EMPTY(*ppActual);
957
958     BOOL retval = CStyle_Array_Long64_In_Ref(ppActual, cActual);
959     ChangeArrayValue(*ppActual, cActual);
960
961     return retval;
962 }
963
964 extern "C" DLL_EXPORT BOOL CStyle_Array_ULong64_InOut_Ref(ULONG64 **ppActual, int cActual)
965 {
966     CHECK_PARAM_NOT_EMPTY(*ppActual);
967
968     BOOL retval = CStyle_Array_ULong64_In_Ref(ppActual, cActual);
969     ChangeArrayValue(*ppActual, cActual);
970
971     return retval;
972 }
973
974 extern "C" DLL_EXPORT BOOL CStyle_Array_Double_InOut_Ref(DOUBLE **ppActual, int cActual)
975 {
976     CHECK_PARAM_NOT_EMPTY(*ppActual);
977
978     BOOL retval = CStyle_Array_Double_In_Ref(ppActual, cActual);
979     ChangeArrayValue(*ppActual, cActual);
980
981     return retval;
982 }
983
984 extern "C" DLL_EXPORT BOOL CStyle_Array_Float_InOut_Ref(FLOAT **ppActual, int cActual)
985 {
986     CHECK_PARAM_NOT_EMPTY(*ppActual);
987
988     BOOL retval = CStyle_Array_Float_In_Ref(ppActual, cActual);
989     ChangeArrayValue(*ppActual, cActual);
990
991     return retval;
992 }
993
994 extern "C" DLL_EXPORT BOOL CStyle_Array_Byte_InOut_Ref(BYTE **ppActual, int cActual)
995 {
996     CHECK_PARAM_NOT_EMPTY(*ppActual);
997
998     BOOL retval = CStyle_Array_Byte_In_Ref(ppActual, cActual);
999     ChangeArrayValue(*ppActual, cActual);
1000
1001     return retval;
1002 }
1003
1004 extern "C" DLL_EXPORT BOOL CStyle_Array_Char_InOut_Ref(CHAR **ppActual, int cActual)
1005 {
1006     CHECK_PARAM_NOT_EMPTY(*ppActual);
1007
1008     BOOL retval = CStyle_Array_Char_In_Ref(ppActual, cActual);
1009     ChangeArrayValue(*ppActual, cActual);
1010
1011     return retval;
1012 }
1013
1014 extern "C" DLL_EXPORT BOOL CStyle_Array_LPCSTR_InOut_Ref(LPCSTR **ppActual, int cActual)
1015 {
1016     CHECK_PARAM_NOT_EMPTY(*ppActual);
1017
1018     BOOL retval = CStyle_Array_LPCSTR_In_Ref(ppActual, cActual);
1019     ChangeArrayValue(*ppActual, cActual);
1020
1021     return retval;
1022 }
1023
1024 extern "C" DLL_EXPORT BOOL CStyle_Array_LPSTR_InOut_Ref(LPSTR **ppActual, int cActual)
1025 {
1026     CHECK_PARAM_NOT_EMPTY(*ppActual);
1027
1028     BOOL retval = CStyle_Array_LPSTR_In_Ref(ppActual, cActual);
1029     ChangeArrayValue(*ppActual, cActual);
1030
1031     return retval;
1032 }
1033
1034 extern "C" DLL_EXPORT BOOL CStyle_Array_Struct_InOut_Ref(TestStruct **ppActual, int cActual)
1035 {
1036     CHECK_PARAM_NOT_EMPTY(*ppActual);
1037
1038     BOOL retval = CStyle_Array_Struct_In_Ref(ppActual, cActual);
1039     ChangeArrayValue(*ppActual, cActual);
1040
1041     return retval;
1042 }
1043
1044 extern "C" DLL_EXPORT BOOL CStyle_Array_Bool_InOut_Ref(BOOL **ppActual, int cActual)
1045 {
1046     CHECK_PARAM_NOT_EMPTY(*ppActual);
1047
1048     BOOL retval = CStyle_Array_Bool_In_Ref(ppActual, cActual);
1049
1050     BOOL *pArray = *ppActual;
1051     for (int i = 0; i < cActual; ++i)
1052     {
1053         if (i % 2 != 0)
1054             pArray[i] = TRUE;
1055         else
1056             pArray[i] = FALSE;
1057     }
1058
1059     return retval;
1060 }
1061
1062 ////////////////////////////////Added marshal array of struct as LPArray//////////////////////////////////
1063 extern "C" DLL_EXPORT BOOL MarshalArrayOfStructAsLPArrayByVal(S2 *pActual, int cActual, S2* pExpect)
1064 {
1065     bool breturn = true;
1066     S2 *correctArr = pExpect;
1067     if (!(ValidateS2LPArray(pActual, correctArr, cActual)))
1068     {
1069         breturn = false;
1070     }
1071     for (int j = 0; j < cActual; j++)
1072     {
1073         InstanceS2(&pActual[j], 0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4);
1074     }
1075     return breturn;
1076 }
1077
1078 extern "C" DLL_EXPORT BOOL MarshalArrayOfStructAsLPArrayByRef(S2 **pActual, int cActual, S2* pExpect)
1079 {
1080     return MarshalArrayOfStructAsLPArrayByVal(*pActual, cActual, pExpect);
1081 }
1082
1083 extern "C" DLL_EXPORT BOOL MarshalArrayOfStructAsLPArrayByValOut(S2 *pActual, int cActual)
1084 {
1085     BOOL breturn = true;
1086     for (int j = 0; j < cActual; j++)
1087     {
1088         InstanceS2(&pActual[j], 0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4);
1089     }
1090     return breturn;
1091 }
1092
1093 extern "C" DLL_EXPORT BOOL MarshalArrayOfStructAsLPArrayByValInOut(S2 *pActual, int cActual)
1094 {
1095     BOOL breturn = true;
1096     return breturn;
1097 }
1098
1099 extern "C" DLL_EXPORT BOOL MarshalArrayOfStructAsLPArrayByRefOut(S2 **pActual, int cActual)
1100 {
1101     BOOL breturn = true;
1102     for (int j = 0; j < cActual; j++)
1103     {
1104         InstanceS2(&((*pActual)[j]), 0, 32, 0, 16, 0, 8, 0, 16, 0, 64, 64.0F, 6.4);
1105     }
1106     return breturn;
1107 }