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 <iostream>
6#include <xplatform.h>
7#include "MarshalArray.h"
8
9using namespace std;
10
11/*----------------------------------------------------------------------------
12macro definition
13----------------------------------------------------------------------------*/
14
15#define INIT_EXPECTED(__type, __size) \
16 __type expected[(__size)]; \
17 for ( size_t i = 0; i < (__size); ++i) \
18 expected[i] = (__type)i
19
20#define INIT_EXPECTED_STRUCT(__type, __size, __array_type) \
21 __type *expected = (__type *)CoreClrAlloc( sizeof(__type) ); \
22 for ( size_t i = 0; i < (__size); ++i) \
23 expected->arr[i] = (__array_type)i
24
25#define EQUALS(__actual, __cActual, __expected) Equals((__actual), (__cActual), (__expected), (int)sizeof(__expected) / sizeof(__expected[0]))
26
27/*----------------------------------------------------------------------------
28struct definition
29----------------------------------------------------------------------------*/
30
31typedef struct { INT arr[ARRAY_SIZE]; } S_INTArray;
32typedef struct { UINT arr[ARRAY_SIZE]; } S_UINTArray;
33typedef struct { SHORT arr[ARRAY_SIZE]; } S_SHORTArray;
34typedef struct { WORD arr[ARRAY_SIZE]; } S_WORDArray;
35typedef struct { LONG64 arr[ARRAY_SIZE]; } S_LONG64Array;
36
37typedef struct { ULONG64 arr[ARRAY_SIZE]; } S_ULONG64Array;
38typedef struct { DOUBLE arr[ARRAY_SIZE]; } S_DOUBLEArray;
39typedef struct { FLOAT arr[ARRAY_SIZE]; } S_FLOATArray;
40typedef struct { BYTE arr[ARRAY_SIZE]; } S_BYTEArray;
41typedef struct { CHAR arr[ARRAY_SIZE]; } S_CHARArray;
42
43typedef struct { LPSTR arr[ARRAY_SIZE]; } S_LPSTRArray;
44typedef struct { LPCSTR arr[ARRAY_SIZE]; } S_LPCSTRArray;
45#ifdef _WIN32
46typedef struct { BSTR arr[ARRAY_SIZE]; } S_BSTRArray;
47#endif
48
49//struct array in a struct
50
51typedef struct { TestStruct arr[ARRAY_SIZE]; } S_StructArray;
52
53typedef struct { BOOL arr[ARRAY_SIZE]; } S_BOOLArray;
54
55/*----------------------------------------------------------------------------
56helper function
57----------------------------------------------------------------------------*/
58
59TestStruct* InitTestStruct()
60{
61 TestStruct *expected = (TestStruct *)CoreClrAlloc( sizeof(TestStruct) * ARRAY_SIZE );
62
63 for ( int i = 0; i < ARRAY_SIZE; i++)
64 {
65 expected[i].x = i;
66 expected[i].d = i;
67 expected[i].l = i;
68 expected[i].str = ToString(i);
69 }
70
71 return expected;
72}
73
74template<typename T>
75BOOL Equals(T *pActual, int cActual, T *pExpected, int cExpected)
76{
77 if ( pActual == NULL && pExpected == NULL )
78 return TRUE;
79 else if ( cActual != cExpected )
80 {
81 printf("WARNING: Test error - %s\n", __FUNCSIG__);
82 printf("Array Length: expected: %d, actual: %d\n", cExpected, cActual);
83 return FALSE;
84 }
85
86 for ( size_t i = 0; i < ((size_t) cExpected); ++i )
87 {
88 if ( !IsObjectEquals(pActual[i], pExpected[i]) )
89 {
90 printf("WARNING: Test error - %s\n", __FUNCSIG__);
91 printf("Array Element Not Equal: index: %d", static_cast<int>(i));
92 return FALSE;
93 }
94 }
95
96 return TRUE;
97}
98
99bool TestStructEquals(TestStruct Actual[], TestStruct Expected[])
100{
101 if ( Actual == NULL && Expected == NULL )
102 return true;
103 else if ( Actual == NULL && Expected != NULL )
104 return false;
105 else if ( Actual != NULL && Expected == NULL )
106 return false;
107
108 for ( int i = 0; i < ARRAY_SIZE; ++i )
109 {
110 if ( !(IsObjectEquals(Actual[i].x, Expected[i].x) &&
111 IsObjectEquals(Actual[i].d, Expected[i].d) &&
112 IsObjectEquals(Actual[i].l, Expected[i].l) &&
113 IsObjectEquals(Actual[i].str, Expected[i].str) ))
114 {
115 printf("WARNING: Test error - %s\n", __FUNCSIG__);
116 return false;
117 }
118 }
119
120 return true;
121}
122
123/*----------------------------------------------------------------------------
124
125Function
126
127----------------------------------------------------------------------------*/
128
129/*----------------------------------------------------------------------------
130marshal sequential strut
131----------------------------------------------------------------------------*/
132extern "C" DLL_EXPORT BOOL __cdecl TakeIntArraySeqStructByVal( S_INTArray s, int size )
133{
134 CHECK_PARAM_NOT_EMPTY( s.arr );
135 INIT_EXPECTED( INT, ARRAY_SIZE );
136 return Equals( s.arr, size, expected, ARRAY_SIZE );
137}
138
139extern "C" DLL_EXPORT BOOL __cdecl TakeUIntArraySeqStructByVal( S_UINTArray s, int size )
140{
141 CHECK_PARAM_NOT_EMPTY( s.arr );
142 INIT_EXPECTED( UINT, ARRAY_SIZE );
143 return Equals( s.arr, size, expected, ARRAY_SIZE );
144}
145
146extern "C" DLL_EXPORT BOOL __cdecl TakeShortArraySeqStructByVal( S_SHORTArray s, int size )
147{
148 CHECK_PARAM_NOT_EMPTY( s.arr );
149 INIT_EXPECTED( SHORT, ARRAY_SIZE );
150 return Equals( s.arr, size, expected, ARRAY_SIZE );
151}
152
153extern "C" DLL_EXPORT BOOL __cdecl TakeWordArraySeqStructByVal( S_WORDArray s, int size )
154{
155 CHECK_PARAM_NOT_EMPTY( s.arr );
156 INIT_EXPECTED( WORD, ARRAY_SIZE );
157 return Equals( s.arr, size, expected, ARRAY_SIZE );
158}
159
160extern "C" DLL_EXPORT BOOL __cdecl TakeLong64ArraySeqStructByVal( S_LONG64Array s, int size )
161{
162 CHECK_PARAM_NOT_EMPTY( s.arr );
163 INIT_EXPECTED( LONG64, ARRAY_SIZE );
164 return Equals( s.arr, size, expected, ARRAY_SIZE );
165}
166
167extern "C" DLL_EXPORT BOOL __cdecl TakeULong64ArraySeqStructByVal( S_ULONG64Array s, int size )
168{
169 CHECK_PARAM_NOT_EMPTY( s.arr );
170 INIT_EXPECTED( ULONG64, ARRAY_SIZE );
171 return Equals( s.arr, size, expected, ARRAY_SIZE );
172}
173
174extern "C" DLL_EXPORT BOOL __cdecl TakeDoubleArraySeqStructByVal( S_DOUBLEArray s, int size )
175{
176 CHECK_PARAM_NOT_EMPTY( s.arr );
177 INIT_EXPECTED( DOUBLE, ARRAY_SIZE );
178 return Equals( s.arr, size, expected, ARRAY_SIZE );
179}
180
181extern "C" DLL_EXPORT BOOL __cdecl TakeFloatArraySeqStructByVal( S_FLOATArray s, int size )
182{
183 CHECK_PARAM_NOT_EMPTY( s.arr );
184 INIT_EXPECTED( FLOAT, ARRAY_SIZE );
185 return Equals( s.arr, size, expected, ARRAY_SIZE );
186}
187
188extern "C" DLL_EXPORT BOOL __cdecl TakeByteArraySeqStructByVal( S_BYTEArray s, int size )
189{
190 CHECK_PARAM_NOT_EMPTY( s.arr );
191 INIT_EXPECTED( BYTE, ARRAY_SIZE );
192 return Equals( s.arr, size, expected, ARRAY_SIZE );
193}
194
195extern "C" DLL_EXPORT BOOL __cdecl TakeCharArraySeqStructByVal( S_CHARArray s, int size )
196{
197 CHECK_PARAM_NOT_EMPTY( s.arr );
198 INIT_EXPECTED( CHAR, ARRAY_SIZE );
199 return Equals( s.arr, size, expected, ARRAY_SIZE );
200}
201
202extern "C" DLL_EXPORT BOOL __cdecl TakeLPSTRArraySeqStructByVal( S_LPSTRArray s, int size )
203{
204 CHECK_PARAM_NOT_EMPTY( s.arr );
205
206 LPSTR expected[ARRAY_SIZE];
207 for ( int i = 0; i < ARRAY_SIZE; ++i )
208 expected[i] = ToString(i);
209
210 return Equals( s.arr, size, expected, ARRAY_SIZE );
211}
212
213extern "C" DLL_EXPORT BOOL __cdecl TakeLPCSTRArraySeqStructByVal( S_LPCSTRArray s, int size )
214{
215 CHECK_PARAM_NOT_EMPTY( s.arr );
216
217 LPSTR expected[ARRAY_SIZE];
218 for ( int i = 0; i < ARRAY_SIZE; ++i )
219 expected[i] = ToString(i);
220
221 return Equals( s.arr, size, (LPCSTR *)expected, ARRAY_SIZE );
222}
223
224#ifdef _WIN32
225extern "C" DLL_EXPORT BOOL __cdecl TakeBSTRArraySeqStructByVal( S_BSTRArray s, int size )
226{
227 CHECK_PARAM_NOT_EMPTY( s.arr );
228
229 BSTR expected[ARRAY_SIZE];
230 for ( int i = 0; i < ARRAY_SIZE; ++i )
231 expected[i] = ToBSTR(i);
232
233 return Equals( s.arr, size, expected, ARRAY_SIZE );
234}
235#endif
236
237extern "C" DLL_EXPORT BOOL __cdecl TakeStructArraySeqStructByVal( S_StructArray s, int size )
238{
239 CHECK_PARAM_NOT_EMPTY( s.arr );
240
241 TestStruct *expected = InitTestStruct();
242 return TestStructEquals( s.arr,expected );
243}
244
245/*----------------------------------------------------------------------------
246marshal sequential class
247----------------------------------------------------------------------------*/
248extern "C" DLL_EXPORT BOOL __cdecl TakeIntArraySeqClassByVal( S_INTArray *s, int size )
249{
250 return TakeIntArraySeqStructByVal( *s, size );
251}
252
253extern "C" DLL_EXPORT BOOL __cdecl TakeUIntArraySeqClassByVal( S_UINTArray *s, int size )
254{
255 return TakeUIntArraySeqStructByVal( *s, size );
256}
257
258extern "C" DLL_EXPORT BOOL __cdecl TakeShortArraySeqClassByVal( S_SHORTArray *s, int size )
259{
260 return TakeShortArraySeqStructByVal( *s, size );
261}
262
263extern "C" DLL_EXPORT BOOL __cdecl TakeWordArraySeqClassByVal( S_WORDArray *s, int size )
264{
265 return TakeWordArraySeqStructByVal( *s, size );
266}
267
268extern "C" DLL_EXPORT BOOL __cdecl TakeLong64ArraySeqClassByVal( S_LONG64Array *s, int size )
269{
270 return TakeLong64ArraySeqStructByVal( *s, size );
271}
272
273extern "C" DLL_EXPORT BOOL __cdecl TakeULong64ArraySeqClassByVal( S_ULONG64Array *s, int size )
274{
275 return TakeULong64ArraySeqStructByVal( *s, size );
276}
277
278extern "C" DLL_EXPORT BOOL __cdecl TakeDoubleArraySeqClassByVal( S_DOUBLEArray *s, int size )
279{
280 return TakeDoubleArraySeqStructByVal( *s, size );
281}
282
283extern "C" DLL_EXPORT BOOL __cdecl TakeFloatArraySeqClassByVal( S_FLOATArray *s, int size )
284{
285 return TakeFloatArraySeqStructByVal( *s, size );
286}
287
288extern "C" DLL_EXPORT BOOL __cdecl TakeByteArraySeqClassByVal( S_BYTEArray *s, int size )
289{
290 return TakeByteArraySeqStructByVal( *s, size );
291}
292
293extern "C" DLL_EXPORT BOOL __cdecl TakeCharArraySeqClassByVal( S_CHARArray *s, int size )
294{
295 return TakeCharArraySeqStructByVal( *s, size );
296}
297
298extern "C" DLL_EXPORT BOOL __cdecl TakeLPSTRArraySeqClassByVal( S_LPSTRArray *s, int size )
299{
300 return TakeLPSTRArraySeqStructByVal( *s, size );
301}
302
303extern "C" DLL_EXPORT BOOL __cdecl TakeLPCSTRArraySeqClassByVal( S_LPCSTRArray *s, int size )
304{
305 return TakeLPCSTRArraySeqStructByVal( *s, size );
306}
307
308#ifdef _WIN32
309extern "C" DLL_EXPORT BOOL __cdecl TakeBSTRArraySeqClassByVal( S_BSTRArray *s, int size )
310{
311 return TakeBSTRArraySeqStructByVal( *s, size );
312}
313#endif
314
315extern "C" DLL_EXPORT BOOL __cdecl TakeStructArraySeqClassByVal( S_StructArray *s, int size )
316{
317 return TakeStructArraySeqStructByVal( *s, size );
318}
319
320/*----------------------------------------------------------------------------
321marshal explicit struct
322----------------------------------------------------------------------------*/
323extern "C" DLL_EXPORT BOOL __cdecl TakeIntArrayExpStructByVal( S_INTArray s, int size )
324{
325 return TakeIntArraySeqStructByVal( s, size );
326}
327
328extern "C" DLL_EXPORT BOOL __cdecl TakeUIntArrayExpStructByVal( S_UINTArray s, int size )
329{
330 return TakeUIntArraySeqStructByVal( s, size );
331}
332
333extern "C" DLL_EXPORT BOOL __cdecl TakeShortArrayExpStructByVal( S_SHORTArray s, int size )
334{
335 return TakeShortArraySeqStructByVal( s, size );
336}
337
338extern "C" DLL_EXPORT BOOL __cdecl TakeWordArrayExpStructByVal( S_WORDArray s, int size )
339{
340 return TakeWordArraySeqStructByVal( s, size );
341}
342
343extern "C" DLL_EXPORT BOOL __cdecl TakeLong64ArrayExpStructByVal( S_LONG64Array s, int size )
344{
345 return TakeLong64ArraySeqStructByVal( s, size );
346}
347
348extern "C" DLL_EXPORT BOOL __cdecl TakeULong64ArrayExpStructByVal( S_ULONG64Array s, int size )
349{
350 return TakeULong64ArraySeqStructByVal( s, size );
351}
352
353extern "C" DLL_EXPORT BOOL __cdecl TakeDoubleArrayExpStructByVal( S_DOUBLEArray s, int size )
354{
355 return TakeDoubleArraySeqStructByVal( s, size );
356}
357
358extern "C" DLL_EXPORT BOOL __cdecl TakeFloatArrayExpStructByVal( S_FLOATArray s, int size )
359{
360 return TakeFloatArraySeqStructByVal( s, size );
361}
362
363extern "C" DLL_EXPORT BOOL __cdecl TakeByteArrayExpStructByVal( S_BYTEArray s, int size )
364{
365 return TakeByteArraySeqStructByVal( s, size );
366}
367
368extern "C" DLL_EXPORT BOOL __cdecl TakeCharArrayExpStructByVal( S_CHARArray s, int size )
369{
370 return TakeCharArraySeqStructByVal( s, size );
371}
372
373extern "C" DLL_EXPORT BOOL __cdecl TakeLPSTRArrayExpStructByVal( S_LPSTRArray s, int size )
374{
375 return TakeLPSTRArraySeqStructByVal( s, size );
376}
377
378extern "C" DLL_EXPORT BOOL __cdecl TakeLPCSTRArrayExpStructByVal( S_LPCSTRArray s, int size )
379{
380 return TakeLPCSTRArraySeqStructByVal( s, size );
381}
382
383#ifdef _WIN32
384extern "C" DLL_EXPORT BOOL __cdecl TakeBSTRArrayExpStructByVal( S_BSTRArray s, int size )
385{
386 return TakeBSTRArraySeqStructByVal( s, size );
387}
388#endif
389
390extern "C" DLL_EXPORT BOOL __cdecl TakeStructArrayExpStructByVal( S_StructArray s, int size )
391{
392 return TakeStructArraySeqStructByVal( s, size );
393}
394
395/*----------------------------------------------------------------------------
396marshal explicit class
397----------------------------------------------------------------------------*/
398extern "C" DLL_EXPORT BOOL __cdecl TakeIntArrayExpClassByVal( S_INTArray *s, int size )
399{
400 return TakeIntArraySeqStructByVal( *s, size );
401}
402
403extern "C" DLL_EXPORT BOOL __cdecl TakeUIntArrayExpClassByVal( S_UINTArray *s, int size )
404{
405 return TakeUIntArraySeqStructByVal( *s, size );
406}
407
408extern "C" DLL_EXPORT BOOL __cdecl TakeShortArrayExpClassByVal( S_SHORTArray *s, int size )
409{
410 return TakeShortArraySeqStructByVal( *s, size );
411}
412
413extern "C" DLL_EXPORT BOOL __cdecl TakeWordArrayExpClassByVal( S_WORDArray *s, int size )
414{
415 return TakeWordArraySeqStructByVal( *s, size );
416}
417
418extern "C" DLL_EXPORT BOOL __cdecl TakeLong64ArrayExpClassByVal( S_LONG64Array *s, int size )
419{
420 return TakeLong64ArraySeqStructByVal( *s, size );
421}
422
423extern "C" DLL_EXPORT BOOL __cdecl TakeULong64ArrayExpClassByVal( S_ULONG64Array *s, int size )
424{
425 return TakeULong64ArraySeqStructByVal( *s, size );
426}
427
428extern "C" DLL_EXPORT BOOL __cdecl TakeDoubleArrayExpClassByVal( S_DOUBLEArray *s, int size )
429{
430 return TakeDoubleArraySeqStructByVal( *s, size );
431}
432
433extern "C" DLL_EXPORT BOOL __cdecl TakeFloatArrayExpClassByVal( S_FLOATArray *s, int size )
434{
435 return TakeFloatArraySeqStructByVal( *s, size );
436}
437
438extern "C" DLL_EXPORT BOOL __cdecl TakeByteArrayExpClassByVal( S_BYTEArray *s, int size )
439{
440 return TakeByteArraySeqStructByVal( *s, size );
441}
442
443extern "C" DLL_EXPORT BOOL __cdecl TakeCharArrayExpClassByVal( S_CHARArray *s, int size )
444{
445 return TakeCharArraySeqStructByVal( *s, size );
446}
447
448extern "C" DLL_EXPORT BOOL __cdecl TakeLPSTRArrayExpClassByVal( S_LPSTRArray *s, int size )
449{
450 return TakeLPSTRArraySeqStructByVal( *s, size );
451}
452
453extern "C" DLL_EXPORT BOOL __cdecl TakeLPCSTRArrayExpClassByVal( S_LPCSTRArray *s, int size )
454{
455 return TakeLPCSTRArraySeqStructByVal( *s, size );
456}
457
458#ifdef _WIN32
459extern "C" DLL_EXPORT BOOL __cdecl TakeBSTRArrayExpClassByVal( S_BSTRArray *s, int size )
460{
461 return TakeBSTRArraySeqStructByVal( *s, size );
462}
463#endif
464
465extern "C" DLL_EXPORT BOOL __cdecl TakeStructArrayExpClassByVal( S_StructArray *s, int size )
466{
467 return TakeStructArraySeqStructByVal( *s, size );
468}
469
470/*----------------------------------------------------------------------------
471return a struct including a C array
472----------------------------------------------------------------------------*/
473extern "C" DLL_EXPORT S_INTArray* __cdecl S_INTArray_Ret()
474{
475 INIT_EXPECTED_STRUCT( S_INTArray, ARRAY_SIZE, INT );
476
477 return expected;
478}
479
480extern "C" DLL_EXPORT S_UINTArray* __cdecl S_UINTArray_Ret()
481{
482 INIT_EXPECTED_STRUCT( S_UINTArray, ARRAY_SIZE, UINT );
483
484 return expected;
485}
486
487extern "C" DLL_EXPORT S_SHORTArray* __cdecl S_SHORTArray_Ret()
488{
489 INIT_EXPECTED_STRUCT( S_SHORTArray, ARRAY_SIZE, SHORT );
490
491 return expected;
492}
493
494extern "C" DLL_EXPORT S_WORDArray* __cdecl S_WORDArray_Ret()
495{
496 INIT_EXPECTED_STRUCT( S_WORDArray, ARRAY_SIZE, WORD );
497
498 return expected;
499}
500
501extern "C" DLL_EXPORT S_LONG64Array* __cdecl S_LONG64Array_Ret()
502{
503 INIT_EXPECTED_STRUCT( S_LONG64Array, ARRAY_SIZE, LONG64 );
504
505 return expected;
506}
507
508extern "C" DLL_EXPORT S_ULONG64Array* __cdecl S_ULONG64Array_Ret()
509{
510 INIT_EXPECTED_STRUCT( S_ULONG64Array, ARRAY_SIZE, ULONG64 );
511
512 return expected;
513}
514
515extern "C" DLL_EXPORT S_DOUBLEArray* __cdecl S_DOUBLEArray_Ret()
516{
517 INIT_EXPECTED_STRUCT( S_DOUBLEArray, ARRAY_SIZE, DOUBLE );
518
519 return expected;
520}
521
522extern "C" DLL_EXPORT S_FLOATArray* __cdecl S_FLOATArray_Ret()
523{
524 INIT_EXPECTED_STRUCT( S_FLOATArray, ARRAY_SIZE, FLOAT );
525
526 return expected;
527}
528
529extern "C" DLL_EXPORT S_BYTEArray* __cdecl S_BYTEArray_Ret()
530{
531 INIT_EXPECTED_STRUCT( S_BYTEArray, ARRAY_SIZE, BYTE );
532
533 return expected;
534}
535
536extern "C" DLL_EXPORT S_CHARArray* __cdecl S_CHARArray_Ret()
537{
538 INIT_EXPECTED_STRUCT( S_CHARArray, ARRAY_SIZE, CHAR );
539
540 return expected;
541}
542
543extern "C" DLL_EXPORT S_LPSTRArray* __cdecl S_LPSTRArray_Ret()
544{
545 S_LPSTRArray *expected = (S_LPSTRArray *)CoreClrAlloc( sizeof(S_LPSTRArray) );
546 for ( int i = 0; i < ARRAY_SIZE; ++i )
547 expected->arr[i] = ToString(i);
548
549 return expected;
550}
551
552#ifdef _WIN32
553extern "C" DLL_EXPORT S_BSTRArray* __cdecl S_BSTRArray_Ret()
554{
555 S_BSTRArray *expected = (S_BSTRArray *)CoreClrAlloc( sizeof(S_BSTRArray) );
556 for ( int i = 0; i < ARRAY_SIZE; ++i )
557 expected->arr[i] = ToBSTR(i);
558
559 return expected;
560}
561#endif
562
563extern "C" DLL_EXPORT S_StructArray* __cdecl S_StructArray_Ret()
564{
565 S_StructArray *expected = (S_StructArray *)CoreClrAlloc( sizeof(S_StructArray) );
566 for ( int i = 0; i < ARRAY_SIZE; ++i )
567 {
568 expected->arr[i].x = i;
569 expected->arr[i].d = i;
570 expected->arr[i].l = i;
571 expected->arr[i].str = ToString(i);
572 }
573
574 return expected;
575}
576