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 <platformdefines.h> |
6 | |
7 | WCHAR strManaged[] = W("Managed\0String\0" ); |
8 | size_t lenstrManaged = sizeof(strManaged) - sizeof(WCHAR); |
9 | |
10 | WCHAR strReturn[] = W("a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ); |
11 | WCHAR strerrReturn[] = W("error" ); |
12 | |
13 | WCHAR strNative[] = W(" Native" ); |
14 | size_t lenstrNative = sizeof(strNative) - sizeof(WCHAR); |
15 | |
16 | //Test Method1 |
17 | extern "C" BSTR ReturnString() |
18 | { |
19 | return TP_SysAllocString(strReturn); |
20 | } |
21 | |
22 | extern "C" BSTR ReturnErrorString() |
23 | { |
24 | return TP_SysAllocString(strerrReturn); |
25 | } |
26 | |
27 | //Test Method2 |
28 | extern "C" DLL_EXPORT BSTR Marshal_InOut(/*[In,Out]*/BSTR s) |
29 | { |
30 | //Check the Input |
31 | size_t len = TP_SysStringByteLen(s); |
32 | |
33 | if (len != lenstrManaged || memcmp(s,strManaged,lenstrManaged) != 0) |
34 | { |
35 | printf("Error in Function Marshal_InOut(Native Client)\n" ); |
36 | printf("Error: Actual: %d, Expected: %d\n" ,(int32_t) len, (int32_t)lenstrManaged); |
37 | |
38 | return ReturnErrorString(); |
39 | } |
40 | |
41 | //In-Place Change |
42 | memcpy(s, strNative, len); |
43 | |
44 | //Return |
45 | return ReturnString(); |
46 | } |
47 | |
48 | |
49 | extern "C" DLL_EXPORT BSTR Marshal_Out(/*[Out]*/BSTR s) |
50 | { |
51 | s = TP_SysAllocString(strNative); |
52 | |
53 | //Return |
54 | return ReturnString(); |
55 | } |
56 | |
57 | |
58 | extern "C" DLL_EXPORT BSTR MarshalPointer_InOut(/*[in,out]*/BSTR *s) |
59 | { |
60 | //Check the Input |
61 | size_t len = TP_SysStringByteLen(*s); |
62 | |
63 | if (len != lenstrManaged || memcmp(*s,strManaged,lenstrManaged)!=0) |
64 | { |
65 | printf("Error in Function MarshalPointer_InOut\n" ); |
66 | printf("Error: Expected: %d, Actual: %d" , (int32_t)lenstrManaged, (int32_t)len); |
67 | |
68 | return ReturnErrorString(); |
69 | } |
70 | |
71 | //Allocate New |
72 | TP_SysFreeString(*s); |
73 | *s = TP_SysAllocString(strNative); |
74 | |
75 | //Return |
76 | return ReturnString(); |
77 | } |
78 | |
79 | extern "C" DLL_EXPORT BSTR MarshalPointer_Out(/*[out]*/ BSTR *s) |
80 | { |
81 | *s = TP_SysAllocString(strNative); |
82 | return ReturnString(); |
83 | } |
84 | |
85 | typedef BSTR (__stdcall * Test_DelMarshal_InOut)(/*[in]*/ BSTR s); |
86 | extern "C" DLL_EXPORT BOOL __cdecl RPinvoke_DelMarshal_InOut(Test_DelMarshal_InOut d, /*[in]*/ BSTR s) |
87 | { |
88 | BSTR str = d(s); |
89 | WCHAR ret[] = W("Return\0Return\0" ); |
90 | |
91 | size_t lenstr = TP_SysStringByteLen(str); |
92 | size_t lenret = sizeof(ret) - sizeof(WCHAR); |
93 | |
94 | if (lenret != lenstr || memcmp(str,ret,lenstr) != 0) |
95 | { |
96 | printf("Error in RPinvoke_DelMarshal_InOut, Returned value didn't match\n" ); |
97 | return FALSE; |
98 | } |
99 | |
100 | TP_SysFreeString(str); |
101 | return TRUE; |
102 | } |
103 | |
104 | // |
105 | // PInvokeDef.cs explicitly declares that RPinvoke_DelMarshalPointer_Out uses STDCALL |
106 | // |
107 | typedef BSTR (__cdecl * Test_DelMarshalPointer_Out)(/*[out]*/ BSTR * s); |
108 | extern "C" DLL_EXPORT BOOL __stdcall RPinvoke_DelMarshalPointer_Out(Test_DelMarshalPointer_Out d) |
109 | { |
110 | BSTR str; |
111 | BSTR ret = d(&str); |
112 | |
113 | WCHAR changedstr[] = W("Native\0String\0" ); |
114 | |
115 | size_t lenstr = TP_SysStringByteLen(str); |
116 | size_t lenchangedstr = sizeof(changedstr) - sizeof(WCHAR); |
117 | |
118 | if ( lenstr != lenchangedstr || (memcmp(str,changedstr,lenstr)!=0)) |
119 | { |
120 | printf("Error in RPinvoke_DelMarshalPointer_Out, Value didn't change\n" ); |
121 | return FALSE; |
122 | } |
123 | |
124 | WCHAR expected[] = W("Return\0Return\0" ); |
125 | size_t lenret = TP_SysStringByteLen(ret); |
126 | size_t lenexpected = sizeof(expected) - sizeof(WCHAR); |
127 | |
128 | if (lenret != lenexpected || memcmp(ret,expected,lenret)!=0) |
129 | { |
130 | printf("Error in RPinvoke_DelMarshalPointer_Out, Return vaue is different than expected\n" ); |
131 | return FALSE; |
132 | } |
133 | |
134 | return TRUE; |
135 | } |
136 | |
137 | // |
138 | // PInvokeDef.cs explicitly declares that ReverseP_MarshalStrB_InOut uses STDCALL |
139 | // |
140 | typedef BSTR (__stdcall * Test_Del_MarshalStrB_InOut)(/*[in,out]*/ BSTR s); |
141 | extern "C" DLL_EXPORT BOOL __stdcall ReverseP_MarshalStrB_InOut(Test_Del_MarshalStrB_InOut d, /*[in]*/ BSTR s) |
142 | { |
143 | BSTR ret = d((BSTR)s); |
144 | WCHAR expected[] = W("Return" ); |
145 | size_t lenret = TP_SysStringByteLen(ret); |
146 | size_t lenexpected = sizeof(expected) - sizeof(WCHAR); |
147 | |
148 | if (lenret != lenexpected || memcmp(ret,expected,lenret) != 0) |
149 | { |
150 | printf("Error in ReverseP_MarshalStrB_InOut, Return vaue is different than expected\n" ); |
151 | return FALSE; |
152 | } |
153 | |
154 | WCHAR expectedchange[] = W("m" ); |
155 | size_t lenstr = TP_SysStringByteLen(s); |
156 | size_t lenexpectedchange = sizeof(expectedchange) - sizeof(WCHAR); |
157 | |
158 | if (lenstr != lenexpectedchange || memcmp(s,expectedchange,lenstr) != 0) |
159 | { |
160 | printf("Error in ReverseP_MarshalStrB_InOut, Value didn't get change\n" ); |
161 | return FALSE; |
162 | } |
163 | return TRUE; |
164 | } |
165 | |
166 | typedef struct Person Person; |
167 | struct Person{ |
168 | int age; |
169 | int _padding; |
170 | BSTR name; |
171 | }; |
172 | |
173 | extern "C" DLL_EXPORT BOOL Marshal_Struct_In(Person person) |
174 | { |
175 | if (person.age != 12) |
176 | { |
177 | printf("Error in Marshal_Struct_In, The value for age field is incorrect\n" ); |
178 | return FALSE; |
179 | } |
180 | |
181 | size_t len = TP_SysStringByteLen(person.name); |
182 | if (len != lenstrManaged || memcmp(person.name, strManaged, lenstrManaged) != 0) |
183 | { |
184 | printf("Error in Marshal_Struct_In, The value for name field is incorrect\n" ); |
185 | return FALSE; |
186 | } |
187 | |
188 | return TRUE; |
189 | } |
190 | |
191 | extern "C" DLL_EXPORT BOOL MarshalPointer_Struct_InOut(Person* person) |
192 | { |
193 | if (person->age != 12) |
194 | { |
195 | printf("Error in MarshalPointer_Struct_InOut, The value for age field is incorrect\n" ); |
196 | return FALSE; |
197 | } |
198 | |
199 | size_t len = TP_SysStringByteLen(person->name); |
200 | if (len != lenstrManaged || memcmp(person->name, strManaged, lenstrManaged) != 0) |
201 | { |
202 | printf("Error in MarshalPointer_Struct_InOut, The value for name field is incorrect\n" ); |
203 | return FALSE; |
204 | } |
205 | |
206 | person->age = 21; |
207 | person->name = TP_SysAllocString(strNative); |
208 | return TRUE; |
209 | } |
210 | |
211 | typedef BOOL (* Test_DelMarshal_Struct_In)(Person person); |
212 | extern "C" DLL_EXPORT BOOL RPInvoke_DelMarshal_Struct_In(Test_DelMarshal_Struct_In d) |
213 | { |
214 | Person * pPerson = (Person *)TP_CoTaskMemAlloc(sizeof(Person)); |
215 | pPerson->age = 21; |
216 | pPerson->name = TP_SysAllocString(strNative); |
217 | |
218 | if (!d(*pPerson)) |
219 | { |
220 | printf("Error in RPInvoke_DelMarshal_Struct_In, Managed delegate return false\n" ); |
221 | return FALSE; |
222 | } |
223 | |
224 | return TRUE; |
225 | } |
226 | |
227 | typedef BOOL (* Test_DelMarshalPointer_Struct_InOut)(Person * person); |
228 | extern "C" DLL_EXPORT BOOL RPInvoke_DelMarshalStructPointer_InOut(Test_DelMarshalPointer_Struct_InOut d) |
229 | { |
230 | Person * pPerson = (Person *)TP_CoTaskMemAlloc(sizeof(Person)); |
231 | pPerson->age = 21; |
232 | pPerson->name = TP_SysAllocString(strNative); |
233 | |
234 | if (!d(pPerson)) |
235 | { |
236 | printf("Error in RPInvoke_DelMarshalStructPointer_InOut,The delegate return false\n" ); |
237 | return FALSE; |
238 | } |
239 | |
240 | size_t len = TP_SysStringByteLen(pPerson->name); |
241 | if (len != lenstrManaged || memcmp(pPerson->name, strManaged, lenstrManaged) != 0) |
242 | { |
243 | printf("Error in RPInvoke_DelMarshalStructPointer_InOut,The value for name field for pPerson is incorrect\n" ); |
244 | return FALSE; |
245 | } |
246 | |
247 | return TRUE; |
248 | } |
249 | |
250 | |