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>
6const char* strManaged = "Managed\0String\0";
7size_t lenstrManaged = 7; // the length of strManaged
8
9const char* strReturn = "a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
10const char *strerrReturn = "error";
11
12const char* strNative = " Native\0String\0";
13size_t lenstrNative = 7; //the len of strNative
14
15//Test Method1
16
17extern "C" LPSTR ReturnString()
18{
19 size_t strLength = strlen(strReturn);
20 LPSTR ret = (LPSTR)(CoreClrAlloc(sizeof(char)* (strLength +1)));
21 memset(ret,'\0',strLength+1);
22 strncpy_s(ret,strLength + 1, strReturn, strLength);
23 return ret;
24}
25
26extern "C" LPSTR ReturnErrorString()
27{
28 size_t strLength = strlen(strerrReturn);
29 LPSTR ret = (LPSTR)(CoreClrAlloc(sizeof(char)*(strLength + 1)));
30 memset(ret,'\0',strLength + 1);
31 strncpy_s(ret,strLength + 1,strerrReturn,strLength);
32 return ret;
33}
34
35//Test Method2
36extern "C" DLL_EXPORT LPSTR Marshal_InOut(/*[In,Out]*/LPSTR s)
37{
38 //Check the Input
39 size_t len = strlen(s);
40
41 if((len != lenstrManaged)||(memcmp(s,strManaged,len)!=0))
42 {
43 printf("Error in Function Marshal_InOut(Native Client)\n");
44
45 for(size_t i = 0; i< lenstrManaged;++i)
46 putchar(*(((char *)strManaged)+i));
47
48 for(size_t j = 0; j < len; ++j )
49 putchar(*(((char *)s) + j));
50 return ReturnErrorString();
51 }
52
53 //In-Place Change
54 strncpy_s(s,len + 1,strNative,lenstrNative);
55
56 //Return
57 return ReturnString();
58}
59
60
61extern "C" DLL_EXPORT LPSTR Marshal_Out(/*[Out]*/LPSTR s)
62{
63 s = (LPSTR)(CoreClrAlloc(sizeof(char)*(lenstrNative+1)));
64
65 memset(s,0,lenstrNative+1);
66 //In-Place Change
67 strncpy_s(s,lenstrNative+1,strNative,lenstrNative);
68
69 //Return
70 return ReturnString();
71}
72
73
74extern "C" DLL_EXPORT LPSTR MarshalPointer_InOut(/*[in,out]*/LPSTR *s)
75{
76 //Check the Input
77 size_t len = strlen(*s);
78
79 if((len != lenstrManaged)||(memcmp(*s,strManaged,len)!=0))
80 {
81 printf("Error in Function MarshalPointer_InOut\n");
82
83 for(size_t i = 0; i< lenstrManaged;++i)
84 putchar(*(((char *)strManaged)+i));
85
86 for( size_t j = 0; j < len; ++j)
87 putchar(*(((char *)*s) + j));
88
89 return ReturnErrorString();
90 }
91
92 //Allocate New
93 CoreClrFree(*s);
94 *s = (LPSTR)CoreClrAlloc(sizeof(char)*(lenstrNative+1));
95 memset(*s,0,lenstrNative+1);
96 strncpy_s(*s,len + 1,strNative,lenstrNative);
97
98 //Return
99 return ReturnString();
100}
101
102extern "C" DLL_EXPORT LPSTR MarshalPointer_Out(/*[out]*/ LPSTR *s)
103{
104 *s = (LPSTR)CoreClrAlloc(sizeof(char)*(lenstrNative+1));
105 memset(*s,0,lenstrNative+1);
106 strncpy_s(*s,lenstrNative+1,strNative,lenstrNative);
107
108 return ReturnString();
109}
110
111extern "C" DLL_EXPORT int __cdecl Writeline(char * pFormat, int i, char c, double d, short s, unsigned u)
112{
113 int sum = i;
114 for (size_t it = 0; it < strlen(pFormat); it++)
115 {
116 sum += (int)(*pFormat);
117 }
118 sum += (int)c;
119 sum += (int)d;
120 sum += (int)s;
121 sum += (int)u;
122 return sum;
123}
124
125
126typedef LPCWSTR (__stdcall * Test_DelMarshal_InOut)(/*[in]*/ LPCSTR s);
127extern "C" DLL_EXPORT BOOL __cdecl RPinvoke_DelMarshal_InOut(Test_DelMarshal_InOut d, /*[in]*/ LPCSTR s)
128{
129 LPCWSTR str = d(s);
130 LPCWSTR ret = W("Return");
131
132 size_t lenstr = wcslen(str);
133 size_t lenret = wcslen(ret);
134
135 if((lenret != lenstr)||(wcsncmp(str,ret,lenstr)!=0))
136 {
137 printf("Error in RPinvoke_DelMarshal_InOut, Returned value didn't match\n");
138 return FALSE;
139 }
140
141 CoreClrFree((LPVOID)str);
142
143 return TRUE;
144}
145
146//
147// PInvokeDef.cs explicitly declares that RPinvoke_DelMarshalPointer_Out uses STDCALL
148//
149typedef LPCSTR (__cdecl * Test_DelMarshalPointer_Out)(/*[out]*/ LPSTR * s);
150extern "C" DLL_EXPORT BOOL __stdcall RPinvoke_DelMarshalPointer_Out(Test_DelMarshalPointer_Out d)
151{
152 LPSTR str;
153 LPCSTR ret = d(&str);
154
155 const char* changedstr = "Native";
156
157 size_t lenstr = strlen(str);
158 size_t lenchangedstr = strlen(changedstr);
159
160 if((lenstr != lenchangedstr)||(strncmp(str,changedstr,lenstr)!=0))
161 {
162 printf("Error in RPinvoke_DelMarshal_InOut, Value didn't change\n");
163 return FALSE;
164 }
165
166 LPCSTR expected = "Return";
167 size_t lenret = strlen(ret);
168 size_t lenexpected = strlen(expected);
169
170 if((lenret != lenexpected)||(strncmp(ret,expected,lenret)!=0))
171 {
172 printf("Error in RPinvoke_DelMarshal_InOut, Return vaue is different than expected\n");
173 return FALSE;
174 }
175
176 return TRUE;
177}
178
179//
180// PInvokeDef.cs explicitly declares that ReverseP_MarshalStrB_InOut uses STDCALL
181//
182typedef LPSTR (__stdcall * Test_Del_MarshalStrB_InOut)(/*[in,out]*/ LPSTR s);
183extern "C" DLL_EXPORT BOOL __stdcall ReverseP_MarshalStrB_InOut(Test_Del_MarshalStrB_InOut d, /*[in]*/ LPCSTR s)
184{
185 LPSTR ret = d((LPSTR)s);
186 LPCSTR expected = "Return";
187 size_t lenret = strlen(ret);
188 size_t lenexpected = strlen(expected);
189
190 if((lenret != lenexpected)||(strncmp(ret,expected,lenret)!=0))
191 {
192 printf("Error in ReverseP_MarshalStrB_InOut, Return vaue is different than expected\n");
193 return FALSE;
194 }
195
196 LPCSTR expectedchange = "m";
197 size_t lenstr = strlen(s);
198 size_t lenexpectedchange = strlen(expectedchange);
199
200 if((lenstr != lenexpectedchange)||(strncmp(s,expectedchange,lenstr)!=0))
201 {
202 printf("Error in ReverseP_MarshalStrB_InOut, Value didn't get change\n");
203 return FALSE;
204 }
205 return TRUE;
206}
207