From 77aa9586d5a5aff401f9461de7252c27648a2763 Mon Sep 17 00:00:00 2001 From: Zeng Jiang Date: Wed, 24 Oct 2018 05:05:57 +0800 Subject: [PATCH] Add PInvoke/Delegate tests (#19323) * Add PInvoke/Delegate tests * Initial pass to get Delegate tests building xplat and running with current infrastructure. * Fix BOOL and NULL comparisons. * Fix copy-paste typo * Disable explicit offset tests off-Windows. --- tests/src/Interop/CMakeLists.txt | 2 + .../AsDefault/AsDefaultTest.cs | 64 +++ .../AsDefault/AsDefaultTest.csproj | 43 ++ .../MarshalDelegateAsField/AsFieldNative.cpp | 459 +++++++++++++++++++++ .../AsFunctionPtr/AsFunctionPtrTest.cs | 64 +++ .../AsFunctionPtr/AsFunctionPtrTest.csproj | 42 ++ .../AsInterface/AsInterfaceTest.cs | 73 ++++ .../AsInterface/AsInterfaceTest.csproj | 46 +++ .../Delegate/MarshalDelegateAsField/CMakeLists.txt | 13 + .../MarshalDelegateAsField/RefLib/RefLib.cs | 150 +++++++ .../MarshalDelegateAsField/RefLib/RefLib.csproj | 39 ++ .../AsDefault/AsDefaultTest.cs | 106 +++++ .../AsDefault/AsDefaultTest.csproj | 41 ++ .../AsFunctionPtr/AsFunctionPtrTest.cs | 103 +++++ .../AsFunctionPtr/AsFunctionPtrTest.csproj | 41 ++ .../AsInterface/AsInterfaceTest.cs | 137 ++++++ .../AsInterface/AsInterfaceTest.csproj | 45 ++ .../MarshalDelegateAsParam/AsParamNative.cpp | 444 ++++++++++++++++++++ .../Delegate/MarshalDelegateAsParam/CMakeLists.txt | 14 + 19 files changed, 1926 insertions(+) create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/CMakeLists.txt create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.csproj create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp create mode 100644 tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/CMakeLists.txt diff --git a/tests/src/Interop/CMakeLists.txt b/tests/src/Interop/CMakeLists.txt index 85bc33f..282cda7 100644 --- a/tests/src/Interop/CMakeLists.txt +++ b/tests/src/Interop/CMakeLists.txt @@ -12,6 +12,8 @@ list(APPEND LINK_LIBRARIES_ADDITIONAL platformdefines) SET(CLR_INTEROP_TEST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(common) +add_subdirectory(PInvoke/Delegate/MarshalDelegateAsField) +add_subdirectory(PInvoke/Delegate/MarshalDelegateAsParam) add_subdirectory(PInvoke/Primitives/Int) add_subdirectory(PInvoke/ExactSpelling) add_subdirectory(NativeCallable) diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.cs new file mode 100644 index 0000000..4826787 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; + +class AsDefaultTest +{ + [DllImport("PInvoke_Delegate_AsField")] + extern static int CommonMethod(); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInStruct_Seq(Struct2_FuncPtrAsField1_Seq s); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInStruct_Exp(Struct2_FuncPtrAsField2_Exp s); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInClass_Seq(Class2_FuncPtrAsField3_Seq s); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInClass_Exp(Class2_FuncPtrAsField4_Exp s); + + static int Main() + { + try{ + Console.WriteLine("Scenario 1 : Delegate marshaled as field in struct with Sequential."); + Struct2_FuncPtrAsField1_Seq s = new Struct2_FuncPtrAsField1_Seq(); + s.verification = true; + s.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInStruct_Seq(s), "Delegate marshaled as field in struct with Sequential."); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Console.WriteLine("\n\nScenario 2 : Delegate marshaled as field in struct with Explicit."); + Struct2_FuncPtrAsField2_Exp s2 = new Struct2_FuncPtrAsField2_Exp(); + s2.verification = true; + s2.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInStruct_Exp(s2), "Delegate marshaled as field in struct with Explicit"); + } + + Console.WriteLine("\n\nScenario 3 : Delegate marshaled as field in class with Sequential."); + Class2_FuncPtrAsField3_Seq c3 = new Class2_FuncPtrAsField3_Seq(); + c3.verification = true; + c3.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInClass_Seq(c3), "Delegate marshaled as field in class with Sequential."); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Console.WriteLine("\n\nScenario 4 : Delegate marshaled as field in class with Explicit."); + Class2_FuncPtrAsField4_Exp c4 = new Class2_FuncPtrAsField4_Exp(); + c4.verification = true; + c4.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInClass_Exp(c4), "Delegate marshaled as field in class with Explicit."); + } + return 100; + } catch (Exception e){ + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + } +} diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.csproj new file mode 100644 index 0000000..93908e2 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsDefault/AsDefaultTest.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + AsDefaultTest + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp new file mode 100644 index 0000000..d5fdf86 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp @@ -0,0 +1,459 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include +#include +#include + +/*-----------------------------------------------------------------------------* +* * +* For MarshalDelegateAsField_AsFunctionPtr.cs * +* / MarshalDelegateAsField_AsDefault.cs * +*-----------------------------------------------------------------------------*/ + +typedef int (STDMETHODCALLTYPE *FuncPtr)(); + +//auxiliary verification value +const int COMMONMETHODCALLED_RIGHT_RETVAL = 10; + +extern "C" DLL_EXPORT int STDMETHODCALLTYPE CommonMethod() +{ + printf("\n\tCalling CommonMethodCalled() by FuncPtr..."); + return COMMONMETHODCALLED_RIGHT_RETVAL; +} + +//FuncPtr funcPtr = CommonMethod; + +///////////////////////Struct_Sequential///////////////////////// +typedef struct _Struct1_FuncPtrAsField1_Seq{ + BOOL verification; + FuncPtr funcPtr; +} Struct1_FuncPtrAsField1_Seq; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateAsFieldInStruct_Seq(Struct1_FuncPtrAsField1_Seq sfs) +{ + if(!sfs.verification || sfs.funcPtr == NULL) + { + printf("TakeDelegateAsFieldInStruct_Seq:NULL field member.\n"); + return FALSE; + } + else + { + return sfs.verification && (sfs.funcPtr() == COMMONMETHODCALLED_RIGHT_RETVAL); + } +} + +///////////////////////Struct_Explicit/////////////////////// +typedef struct _Struct1_FuncPtrAsField2_Exp{ + BOOL verification; + int Padding; + FuncPtr funcPtr; +} Struct1_FuncPtrAsField2_Exp; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateAsFieldInStruct_Exp(Struct1_FuncPtrAsField2_Exp sfe) +{ + if(!sfe.verification || sfe.funcPtr == NULL) + { + printf("TakeDelegateAsFieldInStruct_Exp:NULL field member.\n"); + return FALSE; + } + else + { + return sfe.verification && sfe.funcPtr() == COMMONMETHODCALLED_RIGHT_RETVAL; + } +} + +///////////////////////Struct_Sequential///////////////////////// +class Class1_FuncPtrAsField3_Seq{ +public: + BOOL verification; + FuncPtr funcPtr; +} ; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateAsFieldInClass_Seq(Class1_FuncPtrAsField3_Seq *cfs) +{ + if(!cfs->verification || cfs->funcPtr == NULL) + { + printf("TakeDelegateAsFieldInClass_Seq:NULL field member.\n"); + return FALSE; + } + else + { + return cfs->verification && (cfs->funcPtr() == COMMONMETHODCALLED_RIGHT_RETVAL); + } +} + +///////////////////////Struct_Explicit/////////////////////// +class Class1_FuncPtrAsField4_Exp{ +public: + BOOL verification; + int Padding; + FuncPtr funcPtr; +}; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateAsFieldInClass_Exp(Class1_FuncPtrAsField4_Exp *cfe) +{ + if(!cfe->verification || cfe->funcPtr == NULL) + { + printf("TakeDelegateAsFieldInClass_Exp:NULL field member.\n"); + return FALSE; + } + else + { + return cfe->verification && (cfe->funcPtr() == COMMONMETHODCALLED_RIGHT_RETVAL); + } +} + +#ifdef _WIN32 +#include + +/*-----------------------------------------------------------------------------* +* * +* For MarshalDelegateAsField_AsInterface.cs * +* * +*-----------------------------------------------------------------------------*/ + +#import "mscorlib.tlb" no_namespace named_guids raw_interfaces_only rename("ReportEvent","ReportEventNew") + +typedef struct{ + int result1; + int result2; + int result3; +} Result; + +const int COMMONMETHOD1_RESULT = 10; +const int COMMONMETHOD2_RESULT = 20; +const int COMMONMETHOD3_RESULT = 30; + +const Result expected = { + COMMONMETHOD1_RESULT, + COMMONMETHOD2_RESULT, + COMMONMETHOD3_RESULT +}; + +Result result = {0,0,0}; + +void STDMETHODCALLTYPE ResetToZero() +{ + result.result1 = result.result2 = result.result3 = 0; +} + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE CommonMethod1() +{ + printf("\n\tCommonMethod1() Calling...\n"); + result.result1 = COMMONMETHOD1_RESULT; +} + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE CommonMethod2() +{ + printf("\n\tCommonMethod2() Calling...\n"); + result.result2 = COMMONMETHOD2_RESULT; +} + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE CommonMethod3() +{ + printf("\n\tCommonMethod3() Calling...\n"); + result.result3 = COMMONMETHOD3_RESULT; +} + +bool STDMETHODCALLTYPE Verify(Result expectedR, Result resultR) +{ + return expectedR.result1 == resultR.result1 + && expectedR.result2 == resultR.result2 + && expectedR.result3 == resultR.result3; +} + + +typedef struct _Struct3_InterfacePtrAsField1_Seq{ + BOOL verification; + _Delegate * p_dele; +}Struct3_InterfacePtrAsField1_Seq; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Seq(Struct3_InterfacePtrAsField1_Seq sis) +{ + HRESULT hr; + + ResetToZero(); + + if(sis.verification == NULL || sis.p_dele == NULL) + { + printf("NULL field member.\n"); + return FALSE; + } + else + { + hr = sis.p_dele->DynamicInvoke( NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + bool tempBool = sis.verification && Verify( expected, result); + + + //IDispatch::Invoke + ResetToZero(); + + BSTR bstrNames[1]; + bstrNames[0] = SysAllocString(L"DynamicInvoke"); + DISPID dispid = 0; + hr = sis.p_dele->GetIDsOfNames( + IID_NULL, + bstrNames, + sizeof(bstrNames) / sizeof(bstrNames[0]), + GetUserDefaultLCID(), + &dispid); + + SysFreeString(bstrNames[0]); + + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + VARIANT args[1]; + VariantInit(&args[0]); + args[0].vt = VT_ARRAY|VT_VARIANT; + args[0].parray = NULL; + DISPPARAMS params = { args, NULL, 1, 0 }; + + hr = sis.p_dele->Invoke( + dispid, + IID_NULL, + GetUserDefaultLCID(), + DISPATCH_METHOD, + ¶ms, + NULL, + NULL, + NULL); + + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + return tempBool && Verify(expected, result); + } +} + +typedef struct _Struct3_InterfacePtrAsField2_Exp{ + bool verification; + int Padding; + _Delegate * p_dele; +}Struct3_InterfacePtrAsField2_Exp; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Exp(Struct3_InterfacePtrAsField2_Exp sie) +{ + HRESULT hr; + + ResetToZero(); + + if(sie.verification == NULL || sie.p_dele == NULL) + { + printf("NULL field member.\n"); + return FALSE; + } + else + { + hr = sie.p_dele->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + bool tempBool = sie.verification && Verify( expected, result); + + + //IDispatch::Invoke + ResetToZero(); + + BSTR bstrNames[1]; + bstrNames[0] = SysAllocString(L"DynamicInvoke"); + DISPID dispid = 0; + hr = sie.p_dele->GetIDsOfNames( + IID_NULL, + bstrNames, + sizeof(bstrNames) / sizeof(bstrNames[0]), + GetUserDefaultLCID(), + &dispid); + + SysFreeString(bstrNames[0]); + + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + VARIANT args[1]; + VariantInit(&args[0]); + args[0].vt = VT_ARRAY|VT_VARIANT; + args[0].parray = NULL; + DISPPARAMS params = { args, NULL, 1, 0 }; + + hr = sie.p_dele->Invoke( + dispid, + IID_NULL, + GetUserDefaultLCID(), + DISPATCH_METHOD, + ¶ms, + NULL, + NULL, + NULL); + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + return tempBool && Verify(expected, result); + } +} + +class Class3_InterfacePtrAsField3_Seq +{ +public: + bool verification; + _Delegate * p_dele; +}; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Seq(Class3_InterfacePtrAsField3_Seq *cis) +{ + HRESULT hr; + + ResetToZero(); + + if(cis->verification == NULL || cis->p_dele == NULL) + { + printf("NULL field member.\n"); + return FALSE; + } + else + { + hr = (cis->p_dele)->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + bool tempBool = cis->verification && Verify( expected, result); + + + //IDispatch::Invoke + BSTR bstrNames[1]; + bstrNames[0] = SysAllocString(L"DynamicInvoke"); + DISPID dispid = 0; + hr = (cis->p_dele)->GetIDsOfNames( + IID_NULL, + bstrNames, + sizeof(bstrNames) / sizeof(bstrNames[0]), + GetUserDefaultLCID(), + &dispid); + + SysFreeString(bstrNames[0]); + + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + VARIANT args[1]; + VariantInit(&args[0]); + args[0].vt = VT_ARRAY|VT_VARIANT; + args[0].parray = NULL; + DISPPARAMS params = { args, NULL, 1, 0 }; + + hr = (cis->p_dele)->Invoke( + dispid, + IID_NULL, + GetUserDefaultLCID(), + DISPATCH_METHOD, + ¶ms, + NULL, + NULL, + NULL); + + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + return tempBool && Verify(expected, result); + } + +} + +class Class3_InterfacePtrAsField4_Exp{ +public: + bool verification; + int Padding; + _Delegate * p_dele; +}; + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Exp(Class3_InterfacePtrAsField4_Exp *cie) +{ + HRESULT hr; + + ResetToZero(); + + if(cie->verification == NULL || cie->p_dele == NULL) + { + printf("NULL field member.\n"); + return FALSE; + } + else + { + hr = (cie->p_dele)->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + bool tempBool = cie->verification && Verify( expected, result); + + + //IDispatch::Invoke + BSTR bstrNames[1]; + bstrNames[0] = SysAllocString(L"DynamicInvoke"); + DISPID dispid = 0; + hr = (cie->p_dele)->GetIDsOfNames( + IID_NULL, + bstrNames, + sizeof(bstrNames) / sizeof(bstrNames[0]), + GetUserDefaultLCID(), + &dispid); + + SysFreeString(bstrNames[0]); + + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + VARIANT args[1]; + VariantInit(&args[0]); + args[0].vt = VT_ARRAY|VT_VARIANT; + args[0].parray = NULL; + DISPPARAMS params = { args, NULL, 1, 0 }; + + hr = (cie->p_dele)->Invoke( + dispid, + IID_NULL, + GetUserDefaultLCID(), + DISPATCH_METHOD, + ¶ms, + NULL, + NULL, + NULL); + if(FAILED(hr)) + { + printf("\nERROR: Invoke failed: 0x%x\n", (unsigned int)hr); + return FALSE; + } + + return tempBool && Verify(expected, result); + } +} +#endif diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.cs new file mode 100644 index 0000000..3c10bce --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; + +class AsFunctionPtrTest +{ + [DllImport("PInvoke_Delegate_AsField")] + extern static int CommonMethod(); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInStruct_Seq(Struct1_FuncPtrAsField1_Seq s); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInStruct_Exp(Struct1_FuncPtrAsField2_Exp s); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInClass_Seq(Class1_FuncPtrAsField3_Seq s); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool TakeDelegateAsFieldInClass_Exp(Class1_FuncPtrAsField4_Exp s); + + static int Main() + { + try{ + Console.WriteLine("Scenario 1 : Delegate marshaled as field in struct with Sequential."); + Struct1_FuncPtrAsField1_Seq s1 = new Struct1_FuncPtrAsField1_Seq(); + s1.verification = true; + s1.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInStruct_Seq(s1), "Delegate marshaled as field in struct with Sequential."); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // We don't support marshalling explicit structs by-val on the System V x64 ABI + { + Console.WriteLine("\n\nScenario 2 : Delegate marshaled as field in struct with Explicit."); + Struct1_FuncPtrAsField2_Exp s2 = new Struct1_FuncPtrAsField2_Exp(); + s2.verification = true; + s2.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInStruct_Exp(s2), "Delegate marshaled as field in struct with Explicit."); + } + + Console.WriteLine("\n\nScenario 3 : Delegate marshaled as field in class with Sequential."); + Class1_FuncPtrAsField3_Seq c3 = new Class1_FuncPtrAsField3_Seq(); + c3.verification = true; + c3.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInClass_Seq(c3), "Delegate marshaled as field in class with Sequential."); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Console.WriteLine("\n\nScenario 4 : Delegate marshaled as field in class with Explicit."); + Class1_FuncPtrAsField4_Exp c4 = new Class1_FuncPtrAsField4_Exp(); + c4.verification = true; + c4.dele = new Dele(CommonMethod); + Assert.IsTrue(TakeDelegateAsFieldInClass_Exp(c4), "Delegate marshaled as field in class with Explicit."); + } + return 100; + } catch (Exception e){ + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + } +} diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.csproj new file mode 100644 index 0000000..82d3d52 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFunctionPtr/AsFunctionPtrTest.csproj @@ -0,0 +1,42 @@ + + + + + Debug + AnyCPU + AsFunctionPtrTest + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + + + + + + False + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.cs new file mode 100644 index 0000000..798e093 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; + +class AsInterfaceTest +{ + [DllImport("PInvoke_Delegate_AsField")] + extern static void CommonMethod1(); + + [DllImport("PInvoke_Delegate_AsField")] + extern static void CommonMethod2(); + + [DllImport("PInvoke_Delegate_AsField")] + extern static void CommonMethod3(); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool Take_DelegatePtrAsFieldInStruct_Seq(Struct3_InterfacePtrAsField1_Seq sis); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool Take_DelegatePtrAsFieldInStruct_Exp(Struct3_InterfacePtrAsField2_Exp sie); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool Take_DelegatePtrAsFieldInClass_Seq(Class3_InterfacePtrAsField3_Seq cis); + + [DllImport("PInvoke_Delegate_AsField")] + extern static bool Take_DelegatePtrAsFieldInClass_Exp(Class3_InterfacePtrAsField4_Exp cie); + + static int Main() + { + try{ + Console.WriteLine("Scenario 1 : Delegate marshaled as field in struct with Sequential."); + Struct3_InterfacePtrAsField1_Seq sis = new Struct3_InterfacePtrAsField1_Seq(); + sis.verification = true; + sis.dele = new Dele2(CommonMethod1); + sis.dele += new Dele2(CommonMethod2); + sis.dele += new Dele2(CommonMethod3); + Assert.IsTrue(Take_DelegatePtrAsFieldInStruct_Seq(sis), "Delegate marshaled as field in struct with Sequential."); + + Console.WriteLine("\n\nScenario 2 : Delegate marshaled as field in struct with Explicit."); + Struct3_InterfacePtrAsField2_Exp sie = new Struct3_InterfacePtrAsField2_Exp(); + sie.verification = true; + sie.dele = new Dele2(CommonMethod1); + sie.dele += new Dele2(CommonMethod2); + sie.dele += new Dele2(CommonMethod3); + Assert.IsTrue(Take_DelegatePtrAsFieldInStruct_Exp(sie), "Delegate marshaled as field in struct with Explicit."); + + Console.WriteLine("\n\nScenario 3 : Delegate marshaled as field in class with Sequential."); + Class3_InterfacePtrAsField3_Seq cis = new Class3_InterfacePtrAsField3_Seq(); + cis.verification = true; + cis.dele = new Dele2(CommonMethod1); + cis.dele += new Dele2(CommonMethod2); + cis.dele += new Dele2(CommonMethod3); + Assert.IsTrue(Take_DelegatePtrAsFieldInClass_Seq(cis), "Delegate marshaled as field in class with Sequential"); + + Console.WriteLine("\n\nScenario 4 : Delegate marshaled as field in class with Sequential."); + Class3_InterfacePtrAsField4_Exp cie = new Class3_InterfacePtrAsField4_Exp(); + cie.verification = true; + cie.dele = new Dele2(CommonMethod1); + cie.dele += new Dele2(CommonMethod2); + cie.dele += new Dele2(CommonMethod3); + Assert.IsTrue(Take_DelegatePtrAsFieldInClass_Exp(cie), "Delegate marshaled as field in class with Sequential"); + + return 100; + } catch (Exception e){ + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + } +} diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.csproj new file mode 100644 index 0000000..6e0d5b7 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsInterface/AsInterfaceTest.csproj @@ -0,0 +1,46 @@ + + + + + Debug + AnyCPU + AsInterfaceTest + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + true + true + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/CMakeLists.txt b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/CMakeLists.txt new file mode 100644 index 0000000..c0a6fc5 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/CMakeLists.txt @@ -0,0 +1,13 @@ +#VCXPROJ +cmake_minimum_required (VERSION 2.6) +project (PInvoke_Delegate_AsField) +include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake") +include_directories(${INC_PLATFORM_DIR}) +set(SOURCES + AsFieldNative.cpp +) +# add the executable +add_library (PInvoke_Delegate_AsField SHARED ${SOURCES}) +target_link_libraries(PInvoke_Delegate_AsField ${LINK_LIBRARIES_ADDITIONAL}) +# add the install targets +install (TARGETS PInvoke_Delegate_AsField DESTINATION bin) diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs new file mode 100644 index 0000000..a89be58 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs @@ -0,0 +1,150 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +public delegate int Dele(); + +#region Part 1 : Marshaled As FunctionPtr +[StructLayout(LayoutKind.Sequential)] +public struct Struct1_FuncPtrAsField1_Seq +{ + public bool verification; + + [MarshalAs(UnmanagedType.FunctionPtr)] + public Dele dele; +} + +[StructLayout(LayoutKind.Explicit)] +public struct Struct1_FuncPtrAsField2_Exp +{ + [FieldOffset(0)] + public bool verification; + + [FieldOffset(4)] + public Int32 Padding; + + [FieldOffset(8)] + [MarshalAs(UnmanagedType.FunctionPtr)] + public Dele dele; +} + +[StructLayout(LayoutKind.Sequential)] +public class Class1_FuncPtrAsField3_Seq +{ + public bool verification; + + [MarshalAs(UnmanagedType.FunctionPtr)] + public Dele dele; +} + +[StructLayout(LayoutKind.Explicit)] +public class Class1_FuncPtrAsField4_Exp +{ + [FieldOffset(0)] + public bool verification; + + [FieldOffset(4)] + public Int32 Padding; + + [FieldOffset(8)] + [MarshalAs(UnmanagedType.FunctionPtr)] + public Dele dele; +} +#endregion + +#region Part 2 : Marshaled As Default +[StructLayout(LayoutKind.Sequential)] +public struct Struct2_FuncPtrAsField1_Seq +{ + public bool verification; + + public Dele dele; +} + +[StructLayout(LayoutKind.Explicit)] +public struct Struct2_FuncPtrAsField2_Exp +{ + [FieldOffset(0)] + public bool verification; + + [FieldOffset(4)] + public Int32 Padding; + + [FieldOffset(8)] + public Dele dele; +} + +[StructLayout(LayoutKind.Sequential)] +public class Class2_FuncPtrAsField3_Seq +{ + public bool verification; + + public Dele dele; +} + +[StructLayout(LayoutKind.Explicit)] +public class Class2_FuncPtrAsField4_Exp +{ + [FieldOffset(0)] + public bool verification; + + [FieldOffset(4)] + public Int32 Padding; + + [FieldOffset(8)] + public Dele dele; +} +#endregion + +#region Part 3 : Marshaled As Interface +public delegate void Dele2(); + +[StructLayout(LayoutKind.Sequential)] +public struct Struct3_InterfacePtrAsField1_Seq +{ + public bool verification; + + [MarshalAs(UnmanagedType.Interface)] + public Dele2 dele; +} + +[StructLayout(LayoutKind.Explicit)] +public struct Struct3_InterfacePtrAsField2_Exp +{ + [FieldOffset(0)] + public bool verification; + + [FieldOffset(4)] + public Int32 Padding; + + [FieldOffset(8)] + [MarshalAs(UnmanagedType.Interface)] + public Dele2 dele; +} + +[StructLayout(LayoutKind.Sequential)] +public class Class3_InterfacePtrAsField3_Seq +{ + public bool verification; + + [MarshalAs(UnmanagedType.Interface)] + public Dele2 dele; +} + +[StructLayout(LayoutKind.Explicit)] +public class Class3_InterfacePtrAsField4_Exp +{ + [FieldOffset(0)] + public bool verification; + + [FieldOffset(4)] + public Int32 Padding; + + [FieldOffset(8)] + [MarshalAs(UnmanagedType.Interface)] + public Dele2 dele; +} +#endregion \ No newline at end of file diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.csproj new file mode 100644 index 0000000..19685a1 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.csproj @@ -0,0 +1,39 @@ + + + + + Debug + AnyCPU + RefLib + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Library + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + + + + + + False + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.cs new file mode 100644 index 0000000..afb08f3 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.cs @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; + +class AsDefaultTest +{ + [DllImport("PInvoke_Delegate_AsParam")] + extern static int CommonMethodCalled1(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static int CommonMethodCalled2(); + + delegate int Dele(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByValParam(Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByRefParam(ref Dele dele); + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInValParam([In] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInRefParam([In] ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByOutValParam([Out] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByOutRefParam(out Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInOutValParam([In, Out] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInOutRefParam([In, Out] ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static Dele ReturnDelegateByVal(); + + #region "Auxiliary Verification Value" + const int COMMONMETHODCALLED1_RIGHT_RETVAL = 10; + const int COMMONMETHODCALLED2_RIGHT_RETVAL = 20; + #endregion + + static int Main(string[] args) + { + try{ + Console.WriteLine("Scenario 1 : Delegate marshaled by val with default attribute."); + Dele dele1 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByValParam(dele1), "The return value is wrong in TakeDelegateByValParam."); + + Console.WriteLine("\n\nScenario 2 : Delegate marshaled by ref with default attribute."); + Dele dele2 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByRefParam(ref dele2), "Call on Native side"); + Console.WriteLine("\n\tCalling method CommonMethodCalled2() on the managed side..."); + Assert.AreEqual(COMMONMETHODCALLED2_RIGHT_RETVAL, dele2(), "Now dele2 point to method CommonMethodCalled2()"); + + Console.WriteLine("\n\nScenario 3 : Delegate marshaled by val with default attribute."); + Dele dele3 = new Dele(CommonMethodCalled1); + Dele tempDele3 = dele3; + Assert.IsTrue(TakeDelegateByInValParam(dele3), "Calling method CommonMethodCalled1() on the native side..."); + Assert.AreEqual(tempDele3, dele3, "Delegate marshaled by val with default attribute."); + + Console.WriteLine("\n\nScenario 4 : Delegate marshaled by ref with default attribute."); + Dele dele4 = new Dele(CommonMethodCalled1); + Dele tempDele4 = dele4; + Assert.IsTrue(TakeDelegateByInRefParam(ref dele4), "Calling method CommonMethodCalled1() on the native side"); + Assert.AreEqual(tempDele4, dele4, "Delegate marshaled by val with default attribute."); + + Console.WriteLine("\n\nScenario 5 : Delegate marshaled by val with default attribute."); + Dele dele5 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByOutValParam(dele5), "Calling method CommonMethodCalled1() on the native side"); + Assert.AreEqual(COMMONMETHODCALLED1_RIGHT_RETVAL, dele5(), "The Delegate is wrong"); + + Console.WriteLine("\n\nScenario 6 : Delegate marshaled by ref with default attribute."); + Dele dele6 = new Dele(CommonMethodCalled1); + Dele tempDele6 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByOutRefParam(out dele6), "TakeDelegateByOutRefParam"); + Assert.AreEqual(COMMONMETHODCALLED2_RIGHT_RETVAL, dele6(), "Delegate marshaled by ref with default attribute"); + + Console.WriteLine("\n\nScenario 7 : Delegate marshaled by val with default attribute."); + Dele dele7 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByInOutValParam(dele7), "TakeDelegateByInOutValParam"); + Assert.IsNotNull(dele7, "The variable dele7 is null!"); + + Console.WriteLine("\n\nScenario 8 : Delegate marshaled by ref with default attribute."); + Dele dele8 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByInOutRefParam(ref dele8), "TakeDelegateByInOutRefParam"); + Assert.AreEqual(COMMONMETHODCALLED2_RIGHT_RETVAL, dele8(), "dele8 is not point to method CommonMethodCalled2() correctly"); + + Console.WriteLine("\n\nScenario 9 : return Delegate marshaled by val with default attribute."); + Dele dele9 = ReturnDelegateByVal(); + Assert.AreEqual(COMMONMETHODCALLED1_RIGHT_RETVAL, dele9(), "return Delegate marshaled by val with default attribute"); + + return 100; + } catch (Exception e){ + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + } +} diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.csproj new file mode 100644 index 0000000..4b00a04 --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsDefault/AsDefaultTest.csproj @@ -0,0 +1,41 @@ + + + + + Debug + AnyCPU + AsDefaultTest + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + + + + + + False + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.cs new file mode 100644 index 0000000..94e74ed --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.cs @@ -0,0 +1,103 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; + +class AsFunctionPtrTest +{ + [DllImport("PInvoke_Delegate_AsParam")] + extern static int CommonMethodCalled1(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static int CommonMethodCalled2(); + + delegate int Dele(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByValParam([MarshalAs(UnmanagedType.FunctionPtr)]Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInValParam([In, MarshalAs(UnmanagedType.FunctionPtr)]Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByOutValParam([Out, MarshalAs(UnmanagedType.FunctionPtr)]Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInOutValParam([In, Out, MarshalAs(UnmanagedType.FunctionPtr)]Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByRefParam([MarshalAs(UnmanagedType.FunctionPtr)]ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInRefParam([In, MarshalAs(UnmanagedType.FunctionPtr)]ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByOutRefParam([MarshalAs(UnmanagedType.FunctionPtr)]out Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool TakeDelegateByInOutRefParam([In, Out, MarshalAs(UnmanagedType.FunctionPtr)]ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + [return: MarshalAs(UnmanagedType.FunctionPtr)] + extern static Dele ReturnDelegateByVal(); + + const int COMMONMETHODCALLED1_RIGHT_RETVAL = 10; + const int COMMONMETHODCALLED2_RIGHT_RETVAL = 20; + + static int Main(string[] args) + { + try{ + Console.WriteLine("Scenario 1 : Delegate marshaled by val with attribute [MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele1 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByValParam(dele1), "TakeDelegateByValParam"); + + Console.WriteLine("\n\nScenario 2 : Delegate marshaled by ref with attribute [MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele2 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByRefParam(ref dele2), "TakeDelegateByRefParam"); + Assert.AreEqual(COMMONMETHODCALLED2_RIGHT_RETVAL, dele2(), "dele2 is not point to method CommonMethodCalled2() correctly."); + + Console.WriteLine("\n\nScenario 3 : Delegate marshaled by val with attribute [In,MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele3 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByInValParam(dele3), "TakeDelegateByInValParam"); + + Console.WriteLine("\n\nScenario 4 : Delegate marshaled by ref with attribute [In,MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele4 = new Dele(CommonMethodCalled1); + Dele tempDele4 = dele4; + Assert.IsTrue(TakeDelegateByInRefParam(ref dele4), "TakeDelegateByInRefParam"); + Assert.AreEqual(tempDele4, dele4, "dele4 isnt equal to tempDele4"); + + Console.WriteLine("\n\nScenario 5 : Delegate marshaled by val with attribute [Out,MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele5 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByOutValParam(dele5), "TakeDelegateByOutValParam"); + + Console.WriteLine("Scenario 6 : Delegate marshaled by ref with attribute [Out,MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele6 = new Dele(CommonMethodCalled1); + Dele tempDele6 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByOutRefParam(out dele6), "TakeDelegateByOutRefParam"); + Assert.AreNotEqual(tempDele6, dele6, "dele6 shouldn't equal to tempDele6"); + Assert.AreEqual(COMMONMETHODCALLED2_RIGHT_RETVAL, dele6(), "dele6 is not point to method CommonMethodCalled2() correctly."); + + Console.WriteLine("\n\nScenario 7 : Delegate marshaled by val with attribute [In,Out,MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele7 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByInOutValParam(dele7), "TakeDelegateByInOutValParam"); + Assert.IsNotNull(dele7, "dele7 is null"); + + Console.WriteLine("\n\nScenario 8 : Delegate marshaled by ref with attribute [In,Out,MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele8 = new Dele(CommonMethodCalled1); + Assert.IsTrue(TakeDelegateByInOutRefParam(ref dele8), "TakeDelegateByInOutRefParam"); + Assert.AreEqual(COMMONMETHODCALLED2_RIGHT_RETVAL, dele8(), "dele8 is not point to method CommonMethodCalled2() correctly"); + + Console.WriteLine("\n\nScenario 9 : return Delegate marshaled by val with attribute [return:MarshalAs(UnmanagedType.FunctionPtr)]."); + Dele dele9 = ReturnDelegateByVal(); + Assert.AreEqual(COMMONMETHODCALLED1_RIGHT_RETVAL, dele9(), "dele9() return wrong value"); + + return 100; + } catch (Exception e){ + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + } +} diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.csproj new file mode 100644 index 0000000..b4e635b --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsFunctionPtr/AsFunctionPtrTest.csproj @@ -0,0 +1,41 @@ + + + + + Debug + AnyCPU + AsFunctionPtrTest + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + + + + + + False + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs new file mode 100644 index 0000000..b06260b --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs @@ -0,0 +1,137 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; +using TestLibrary; + +class AsInterfaceTest +{ + public delegate void Dele(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByValParam([MarshalAs(UnmanagedType.Interface)] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByRefParam([MarshalAs(UnmanagedType.Interface)] ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByInValParam([In, MarshalAs(UnmanagedType.Interface)] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByInRefParam([In, MarshalAs(UnmanagedType.Interface)] ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByOutValParam([Out, MarshalAs(UnmanagedType.Interface)] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByOutRefParam([Out, MarshalAs(UnmanagedType.Interface)]out Dele dele, [MarshalAs(UnmanagedType.Interface)] Dele deleHelper); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByInOutValParam([In, Out, MarshalAs(UnmanagedType.Interface)] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static bool Take_DelegatePtrByInOutRefParam([In, Out, MarshalAs(UnmanagedType.Interface)] ref Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + [return: MarshalAs(UnmanagedType.Interface)] + extern static Dele ReturnDelegatePtrByVal([MarshalAs(UnmanagedType.Interface)] Dele dele); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static int RetFieldResult1(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static int RetFieldResult2(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static int RetFieldResult3(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static void CommonMethod1(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static void CommonMethod2(); + + [DllImport("PInvoke_Delegate_AsParam")] + extern static void CommonMethod3(); + + const int COMMONMETHOD1_RESULT = 10; + const int COMMONMETHOD2_RESULT = 20; + const int COMMONMETHOD3_RESULT = 30; + + static int Main() + { + try{ + Console.WriteLine("Scenario 1 : Delegate marshaled by val with attribute [MarshalAs(UnmanagedType.Interface)]."); + Dele dele1 = new Dele(CommonMethod1); + dele1 += CommonMethod2; + dele1 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByValParam(dele1), "Take_DelegatePtrByValParam"); + + Console.WriteLine("\n\nScenario 2 : Delegate marshaled by ref with attribute [MarshalAs(MarshalAs(UnmanagedType.Interface)]."); + Dele dele2 = new Dele(CommonMethod1); + dele2 += CommonMethod2; + dele2 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByRefParam(ref dele2), "Take_DelegatePtrByRefParam"); + Assert.IsNull( dele2, "dele2 should equal to null"); + + Console.WriteLine("\n\nScenario 3 : Delegate marshaled by val with attribute [In,MarshalAs(UnmanagedType.Interface)]."); + Dele dele3 = new Dele(CommonMethod1); + dele3 += CommonMethod2; + dele3 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByInValParam(dele3), "Take_DelegatePtrByInValParam"); + + Console.WriteLine("\n\nScenario 4 : Delegate marshaled by ref with attribute [In,MarshalAs(UnmanagedType.Interface)]."); + Dele dele4 = new Dele(CommonMethod1); + dele4 += CommonMethod2; + dele4 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByInRefParam(ref dele4), "Take_DelegatePtrByInRefParam"); + Assert.IsNotNull(dele4, "dele4 does't set to null correctly."); + + Console.WriteLine("\n\nScenario 5 : Delegate marshaled by val with attribute [Out,MarshalAs(UnmanagedType.Interface)]."); + Dele dele5 = new Dele(CommonMethod1); + dele5 += CommonMethod2; + dele5 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByOutValParam(dele5), "Take_DelegatePtrByOutValParam"); + Assert.IsNotNull(dele5, "dele5 does't set to null correctly"); + + Console.WriteLine("\n\nScenario 6 : Delegate marshaled by ref with attribute [Out,MarshalAs(UnmanagedType.Interface)]."); + Dele dele6 = null; + Dele deleHelper = new Dele(CommonMethod1); + deleHelper += CommonMethod2; + Assert.IsTrue(Take_DelegatePtrByOutRefParam(out dele6, deleHelper), "Take_DelegatePtrByOutRefParam"); + dele6(); + Assert.AreEqual(COMMONMETHOD1_RESULT, RetFieldResult1(), "RetFieldResult1 return value is wrong"); + Assert.AreEqual(COMMONMETHOD2_RESULT, RetFieldResult2(), "RetFieldResult2 return value is wrong "); + + Console.WriteLine("\n\nScenario 7 : Delegate marshaled by val with attribute [In,OutMarshalAs(UnmanagedType.Interface)]."); + Dele dele7 = new Dele(CommonMethod1); + dele7 += CommonMethod2; + dele7 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByInOutValParam(dele7), "Take_DelegatePtrByInOutValParam"); + + Console.WriteLine("\n\nScenario 8 : Delegate marshaled by ref with attribute [In,OutMarshalAs(MarshalAs(UnmanagedType.Interface)]."); + Dele dele8 = new Dele(CommonMethod1); + dele8 += CommonMethod2; + dele8 += CommonMethod3; + Assert.IsTrue(Take_DelegatePtrByInOutRefParam(ref dele8), "Take_DelegatePtrByInOutRefParam"); + Assert.IsTrue(dele8 == null, "dele8 does't set to null correctly."); + + Console.WriteLine("\n\nScenario 9 : return Delegate marshaled by val with attribute [return:MarshalAs(UnmanagedType.Interface)]."); + Dele dele9 = new Dele(CommonMethod1); + dele9 += CommonMethod2; + dele9 += CommonMethod3; + Dele tempDele = ReturnDelegatePtrByVal(dele9); + tempDele(); + Assert.AreEqual(COMMONMETHOD1_RESULT, RetFieldResult1(), "RetFieldResult1() return value is wrong"); + Assert.AreEqual(COMMONMETHOD2_RESULT, RetFieldResult2(), "RetFieldResult2() return value is wrong"); + Assert.AreEqual(COMMONMETHOD3_RESULT, RetFieldResult3(), "RetFieldResult3() return value is wrong"); + + return 100; + } catch (Exception e){ + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + } +} diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.csproj b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.csproj new file mode 100644 index 0000000..d43074d --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.csproj @@ -0,0 +1,45 @@ + + + + + Debug + AnyCPU + AsInterfaceTest + 2.0 + {F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\..\..\ + $(DefineConstants);STATIC + true + + true + true + + + + + + + False + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp new file mode 100644 index 0000000..d85babb --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp @@ -0,0 +1,444 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include +#include +#include + +/*-----------------------------------------------------------------------------* +* * +* For MarshalDelegateAsParam_AsFunctionPtr.cs * +* * +*-----------------------------------------------------------------------------*/ + +//auxiliary verification value +const int COMMONMETHODCALLED1_RIGHT_RETVAL = 10; +const int COMMONMETHODCALLED2_RIGHT_RETVAL = 20; + +//common method called by function pointer(Delegate) +extern "C" DLL_EXPORT int STDMETHODCALLTYPE CommonMethodCalled1() +{ + printf("\n\tCalling CommonMethodCalled1() by FuncPtr..."); + return COMMONMETHODCALLED1_RIGHT_RETVAL; +} + +extern "C" DLL_EXPORT int STDMETHODCALLTYPE CommonMethodCalled2() +{ + printf("\n\tCalling CommonMethodCalled2() by FuncPtr..."); + return COMMONMETHODCALLED2_RIGHT_RETVAL; +} + +//define function pointer +typedef int (STDMETHODCALLTYPE *DelegateParam)(); + +//delegate marshalled by val +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByValParam(DelegateParam deleParam) +{ + printf("\tdelegate marshaled by val."); + + //verify return value + if(deleParam == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if( deleParam() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + return TRUE; +} + +//delegate marshalled by ref +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByRefParam(DelegateParam* deleParam) +{ + printf("\n\tdelegate marshaled by ref."); + + //verify value + if((*deleParam) == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if((*deleParam)() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + //make funcptr point to CommonMethodCalled2 + *deleParam = CommonMethodCalled2; + printf("\n\tNow FuncPtr point to CommonMethodCalled2 !"); + //verify value return again + if((*deleParam)() != COMMONMETHODCALLED2_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + return TRUE; +} + +//delegate marshalled by in,val +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByInValParam(DelegateParam deleParam) +{ + printf("\n\tdelegate marshalled by in,val."); + + //verify return value + if(deleParam == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if( deleParam() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + deleParam = CommonMethodCalled2; + + return TRUE; +} + +//delegate marshalled by in,ref +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByInRefParam(DelegateParam* deleParam) +{ + printf("\n\tdelegate marshalled by in,ref."); + + //verify return value + if(*deleParam == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if((*deleParam)() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + *deleParam = CommonMethodCalled2; + + return TRUE; +} + +//delegate marshalled by out,val +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByOutValParam(DelegateParam deleParam) +{ + printf("\n\tdelegate marshalled by out,val."); + + //verify return value + if(deleParam == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if( deleParam() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + return TRUE; +} + +//delegate marshalled by out,ref +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByOutRefParam(DelegateParam* deleParam) +{ + printf("\n\tdelegate marshalled by out,ref."); + + //arg getted should be NULL + //when args ref marshaled as [Out] attribute, the args actually initialized on the native side + if(*deleParam != NULL) + { + printf("\n\tDelegate is not NULL !"); + return FALSE; + } + + //initial value of delegate marshaled + *deleParam = CommonMethodCalled2; + printf("\n\tNow FuncPtr point to CommonMethodCalled2 !"); + + //verify value return again + if((*deleParam)() != COMMONMETHODCALLED2_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + return TRUE; +} + +//delegate marshalled by in,out,val +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByInOutValParam(DelegateParam deleParam) +{ + printf("\n\tdelegate marshalled by in,out,val."); + //verify return value + if(deleParam == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if( deleParam() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + return TRUE; +} + +//delegate marshalled by in,out,ref +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateByInOutRefParam(DelegateParam* deleParam) +{ + printf("\n\tdelegate marshalled by in,out,ref."); + + //verify value + if((*deleParam) == NULL) + { + printf("\n\tNULL delegate!"); + return FALSE; + } + else if((*deleParam)() != COMMONMETHODCALLED1_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + //make funcptr point to CommonMethodCalled2 + *deleParam = CommonMethodCalled2; + printf("\n\tNow FuncPtr point to CommonMethodCalled2 !"); + //verify value return again + if((*deleParam)() != COMMONMETHODCALLED2_RIGHT_RETVAL) + { + printf("\n\tReturn Value Err!"); + return FALSE; + } + + return TRUE; +} + +//ret delegate by val +extern "C" DLL_EXPORT DelegateParam STDMETHODCALLTYPE ReturnDelegateByVal() +{ + printf("\n\tdelegate marshalled by val."); + + return CommonMethodCalled1; +} + +#ifdef _WIN32 + +#include + +/* -----------------------------------------------------------------------------* +* * +* For MarshalDelegateAsParam_AsInterface.cs * +* * +* -----------------------------------------------------------------------------*/ + +#import "mscorlib.tlb" no_namespace named_guids raw_interfaces_only rename("ReportEvent","ReportEventNew") + +typedef struct{ + int result1; + int result2; + int result3; +} Result; + +const int COMMONMETHOD1_RESULT = 10; +const int COMMONMETHOD2_RESULT = 20; +const int COMMONMETHOD3_RESULT = 30; + +const Result expected = { + COMMONMETHOD1_RESULT, + COMMONMETHOD2_RESULT, + COMMONMETHOD3_RESULT +}; + +Result result = {0,0,0}; + +void STDMETHODCALLTYPE ResetToZero() +{ + result.result1 = result.result2 = result.result3 = 0; +} + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE CommonMethod1() +{ + printf("\n\tCommonMethod1() Calling..."); + result.result1 = 10; +} + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE CommonMethod2() +{ + printf("\n\tCommonMethod2() Calling..."); + result.result2 = 20; +} + +extern "C" DLL_EXPORT void STDMETHODCALLTYPE CommonMethod3() +{ + printf("\n\tCommonMethod3() Calling..."); + result.result3 = 30; +} + +BOOL STDMETHODCALLTYPE Verify(Result expectedR, Result resultR) +{ + return expectedR.result1 == resultR.result1 + && expectedR.result2 == resultR.result2 + && expectedR.result3 == resultR.result3; +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByValParam(_Delegate * p_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = p_dele->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + return FALSE; + else + return Verify(expected, result); +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByRefParam(_Delegate **pp_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = (*pp_dele)->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + else + { + *pp_dele = NULL; + return Verify(expected, result); + } +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInValParam(_Delegate * p_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = p_dele->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + else + { + return Verify(expected, result); + } +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInRefParam(_Delegate **pp_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = (*pp_dele)->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + else + { + *pp_dele = NULL; + return Verify(expected, result); + } +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutValParam(_Delegate * p_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = p_dele->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + else + { + p_dele = NULL; + return Verify(expected, result); + } +} + +//verification method +extern "C" DLL_EXPORT int STDMETHODCALLTYPE RetFieldResult1() +{ + return result.result1; +} + +extern "C" DLL_EXPORT int STDMETHODCALLTYPE RetFieldResult2() +{ + return result.result2; +} + +extern "C" DLL_EXPORT int STDMETHODCALLTYPE RetFieldResult3() +{ + return result.result3; +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutRefParam(_Delegate ** pp_dele, _Delegate * pdeleHelper) +{ + printf("In Take_DelegatePtrByOutRefParam native side \n"); + ResetToZero(); + + if( *pp_dele != NULL) + { + return FALSE; + } + else + { + *pp_dele = pdeleHelper; + (*pp_dele)->AddRef(); + return TRUE; + } +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutValParam(_Delegate * p_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = p_dele->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + else + { + return Verify(expected, result); + } +} + +extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutRefParam(_Delegate **pp_dele) +{ + ResetToZero(); + + HRESULT hr; + hr = (*pp_dele)->DynamicInvoke(NULL, NULL); + if(FAILED(hr)) + { + return FALSE; + } + else + { + *pp_dele = NULL; + return Verify(expected, result); + } +} + +extern "C" DLL_EXPORT _Delegate* ReturnDelegatePtrByVal(_Delegate * pdeleHelper) +{ + pdeleHelper->AddRef(); + return pdeleHelper; +} + +#endif diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/CMakeLists.txt b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/CMakeLists.txt new file mode 100644 index 0000000..1be5cfa --- /dev/null +++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/CMakeLists.txt @@ -0,0 +1,14 @@ +#VCXPROJ +cmake_minimum_required (VERSION 2.6) +project (PInvoke_Delegate_AsParam) +include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake") +include_directories(${INC_PLATFORM_DIR}) +set(SOURCES + AsParamNative.cpp +) + +# add the executable +add_library (PInvoke_Delegate_AsParam SHARED ${SOURCES}) +target_link_libraries(PInvoke_Delegate_AsParam ${LINK_LIBRARIES_ADDITIONAL}) +# add the install targets +install (TARGETS PInvoke_Delegate_AsParam DESTINATION bin) -- 2.7.4