| 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 "platformdefines.h" |
| 8 | |
| 9 | DECIMAL g_DECIMAL_MaxValue = { 0, {{ 0, 0 }}, 0xffffffff, {{0xffffffff, 0xffffffff}} }; |
| 10 | DECIMAL g_DECIMAL_MinValue = { 0, {{ 0, DECIMAL_NEG }}, 0xffffffff, {{0xffffffff, 0xffffffff }}}; |
| 11 | DECIMAL g_DECIMAL_Zero = { 0 }; |
| 12 | |
| 13 | CY g_CY_MaxValue = { {0xffffffff, 0x7fffffff} }; |
| 14 | CY g_CY_MinValue = { {(LONG)0x00000000, (LONG)0x80000000} }; |
| 15 | CY g_CY_Zero = { {0} }; |
| 16 | |
| 17 | typedef struct _Stru_Seq_DecAsStructAsFld |
| 18 | { |
| 19 | int number; |
| 20 | DECIMAL dec; |
| 21 | } Stru_Seq_DecAsStructAsFld; |
| 22 | |
| 23 | typedef struct _Stru_Exp_DecAsCYAsFld |
| 24 | { |
| 25 | WCHAR wc; |
| 26 | CY cy; |
| 27 | } Stru_Exp_DecAsCYAsFld; |
| 28 | |
| 29 | typedef struct _Stru_Seq_DecAsLPStructAsFld |
| 30 | { |
| 31 | DOUBLE dblVal; |
| 32 | CHAR cVal; |
| 33 | DECIMAL* dec; |
| 34 | } Stru_Seq_DecAsLPStructAsFld; |
| 35 | |
| 36 | // As Struct |
| 37 | typedef BOOL (STDMETHODCALLTYPE *Fp_Dec)(DECIMAL*); |
| 38 | typedef DECIMAL (STDMETHODCALLTYPE *Fp_RetDec)(); |
| 39 | typedef BOOL (STDMETHODCALLTYPE *Fp_Stru_Seq_DecAsStructAsFld)(Stru_Seq_DecAsStructAsFld*); |
| 40 | // As CY |
| 41 | typedef BOOL (STDMETHODCALLTYPE *Fp_CY)(CY*); |
| 42 | typedef CY (STDMETHODCALLTYPE *Fp_RetCY)(); |
| 43 | typedef BOOL (STDMETHODCALLTYPE *Fp_Stru_Exp_DecAsCYAsFld)(Stru_Exp_DecAsCYAsFld*); |
| 44 | // As LPStruct |
| 45 | typedef BOOL (STDMETHODCALLTYPE *Fp_DecAsLPStruct)(DECIMAL**); |
| 46 | typedef DECIMAL* (STDMETHODCALLTYPE *Fp_RetDecAsLPStruct)(); |
| 47 | typedef BOOL (STDMETHODCALLTYPE *Fp_Stru_Seq_DecAsLPStructAsFld)(Stru_Seq_DecAsLPStructAsFld*); |
| 48 | |
| 49 | void DecDisplay(const DECIMAL& dec) |
| 50 | { |
| 51 | std::cout << "\twReserved" << "\t\t" << dec.wReserved << "\n" |
| 52 | << "\tscale" << "\t\t" << dec.scale << "\n" |
| 53 | << "\tsign" << "\t\t" << dec.sign << "\n" |
| 54 | << "\tsignscale" << "\t\t" << dec.signscale << "\n" |
| 55 | << "\tHi32" << "\t\t" << dec.Hi32 << "\n" |
| 56 | << "\tLo32" << "\t\t" << dec.Lo32 << "\n" |
| 57 | << "\tMid32" << "\t\t" << dec.Mid32 << "\n" |
| 58 | << "\tLo64" << "\t\t" << dec.Lo64 << std::endl; |
| 59 | } |
| 60 | |
| 61 | template<typename T> |
| 62 | bool operator==(const T& t1, const T& t2) |
| 63 | { |
| 64 | return 0 == memcmp((void*)&t1, (void*)&t2, sizeof(T)); |
| 65 | } |
| 66 | |
| 67 | template<typename T> |
| 68 | bool Equals(LPCSTR err_id, T expected, T actual) |
| 69 | { |
| 70 | if(expected == actual) |
| 71 | return true; |
| 72 | else |
| 73 | { |
| 74 | std::cout << "\t#Native Side Err# -- " << err_id |
| 75 | << "\n\tExpected = " << expected << std::endl; |
| 76 | std::wcout << "\tActual is = " << actual << std::endl; |
| 77 | |
| 78 | return false; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | bool IntEqualsToExpected(LPCSTR err_id, int number, int expected) |
| 83 | { |
| 84 | |
| 85 | if(number == expected) |
| 86 | { |
| 87 | return true; |
| 88 | } |
| 89 | else |
| 90 | { |
| 91 | std::wcout << "\t#Native Side Err# -- " << err_id |
| 92 | << "\n\tnumber Expected = " << expected << std::endl; |
| 93 | |
| 94 | std::wcout << "\tnumber Actual is = " << number << std::endl; |
| 95 | |
| 96 | return false; |
| 97 | } |
| 98 | } |
| 99 | bool DecEqualsToExpected(LPCSTR err_id, const DECIMAL& expected, const DECIMAL& actual) |
| 100 | { |
| 101 | if(expected == actual) |
| 102 | return true; |
| 103 | else |
| 104 | { |
| 105 | std::cout << "\t#Native Side Err # -- " << err_id |
| 106 | << "DECIMAL Expected is :" << std::endl; |
| 107 | DecDisplay(expected); |
| 108 | |
| 109 | std::cout << "\t" << "____________________________________" << std::endl; |
| 110 | |
| 111 | std::cout << "\tDECIMAL Actual is :" << std::endl; |
| 112 | DecDisplay(actual); |
| 113 | |
| 114 | return false; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | bool CYEqualsToExpected(LPCSTR err_id, const CY& expected, const CY& actual) |
| 119 | { |
| 120 | if(expected == actual) |
| 121 | return true; |
| 122 | else |
| 123 | { |
| 124 | std::cout << "\t#Native Side Err# -- " << err_id |
| 125 | << "\n\tCY Expected is :" << "Hi = " << expected.Hi |
| 126 | << "Lo = " << expected.Lo << std::endl; |
| 127 | |
| 128 | std::cout << "\tCY Actual is :" << "Hi = " << actual.Hi |
| 129 | << "Lo = " << actual.Lo << std::endl; |
| 130 | |
| 131 | return false; |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | template<typename T> |
| 136 | T* RetSpecificTypeInstancePtr(T tVal) |
| 137 | { |
| 138 | T* lpT = (T*)CoreClrAlloc(sizeof(T)); |
| 139 | *lpT = tVal; |
| 140 | return lpT; |
| 141 | } |
| 142 | |
| 143 | // As Struct |
| 144 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByInOutRef(Fp_Dec fp) |
| 145 | { |
| 146 | DECIMAL* lpDec = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue); |
| 147 | |
| 148 | if((*fp)(lpDec)) |
| 149 | return DecEqualsToExpected("001.01" , g_DECIMAL_MinValue, *lpDec); |
| 150 | else |
| 151 | return false; |
| 152 | } |
| 153 | |
| 154 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByOutRef(Fp_Dec fp) |
| 155 | { |
| 156 | DECIMAL* lpDec = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue); |
| 157 | |
| 158 | if((*fp)(lpDec)) |
| 159 | return DecEqualsToExpected("001.02" , g_DECIMAL_Zero, *lpDec); |
| 160 | else |
| 161 | return false; |
| 162 | } |
| 163 | |
| 164 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_DecRet(Fp_RetDec fp) |
| 165 | { |
| 166 | return DecEqualsToExpected("001.03" , g_DECIMAL_MinValue, (*fp)()); |
| 167 | } |
| 168 | |
| 169 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeStru_Seq_DecAsStructAsFldByInOutRef(Fp_Stru_Seq_DecAsStructAsFld fp) |
| 170 | { |
| 171 | Stru_Seq_DecAsStructAsFld s = { 1, g_DECIMAL_MaxValue }; |
| 172 | |
| 173 | if((*fp)(&s)) |
| 174 | return DecEqualsToExpected("001.04" , g_DECIMAL_MinValue, s.dec) && IntEqualsToExpected("001.05" , s.number, 2); |
| 175 | else |
| 176 | return false; |
| 177 | } |
| 178 | |
| 179 | // As CY |
| 180 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeCYByInOutRef(Fp_CY fp) |
| 181 | { |
| 182 | CY* lpCy = RetSpecificTypeInstancePtr(g_CY_MaxValue); |
| 183 | |
| 184 | if((*fp)(lpCy)) |
| 185 | return CYEqualsToExpected("002.01" , g_CY_MinValue, *lpCy); |
| 186 | else |
| 187 | return false; |
| 188 | } |
| 189 | |
| 190 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeCYByOutRef(Fp_CY fp) |
| 191 | { |
| 192 | CY* lpCy = RetSpecificTypeInstancePtr(g_CY_MaxValue); |
| 193 | |
| 194 | if((*fp)(lpCy)) |
| 195 | return CYEqualsToExpected("002.02" , g_CY_Zero, *lpCy); |
| 196 | else |
| 197 | return false; |
| 198 | } |
| 199 | |
| 200 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_CYRet(Fp_RetCY fp) |
| 201 | { |
| 202 | return CYEqualsToExpected("002.03" , g_CY_MinValue, (*fp)()); |
| 203 | } |
| 204 | |
| 205 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeStru_Exp_DecAsCYAsFldByOutRef(Fp_Stru_Exp_DecAsCYAsFld fp) |
| 206 | { |
| 207 | Stru_Exp_DecAsCYAsFld s = { 0 }; |
| 208 | |
| 209 | if((*fp)(&s)) |
| 210 | return CYEqualsToExpected("002.04" , g_CY_MaxValue, s.cy) && Equals("002.05" , W('C'), s.wc); |
| 211 | else |
| 212 | return false; |
| 213 | } |
| 214 | |
| 215 | // As LPStrcut |
| 216 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByInOutRefAsLPStruct(Fp_DecAsLPStruct fp) |
| 217 | { |
| 218 | DECIMAL* lpDec = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue); |
| 219 | DECIMAL** lppDec = &lpDec; |
| 220 | |
| 221 | if((*fp)(lppDec)) |
| 222 | return DecEqualsToExpected("003.01" , g_DECIMAL_MinValue, **lppDec); |
| 223 | else |
| 224 | return false; |
| 225 | } |
| 226 | |
| 227 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_TakeDecByOutRefAsLPStruct(Fp_DecAsLPStruct fp) |
| 228 | { |
| 229 | DECIMAL* lpDecAsLPStruct = RetSpecificTypeInstancePtr(g_DECIMAL_MaxValue); |
| 230 | DECIMAL** lppDecAsLPStruct = &lpDecAsLPStruct; |
| 231 | |
| 232 | if((*fp)(lppDecAsLPStruct)) |
| 233 | return DecEqualsToExpected("003.02" , g_DECIMAL_Zero, **lppDecAsLPStruct); |
| 234 | else |
| 235 | return false; |
| 236 | } |
| 237 | |
| 238 | //************** ReverseCall Return Int From Net **************// |
| 239 | typedef int (*Fp_RetInt)(); |
| 240 | extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE ReverseCall_IntRet(Fp_RetInt fp) |
| 241 | { |
| 242 | return 0x12345678 == (*fp)(); |
| 243 | } |
| 244 | |