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)
--- /dev/null
+// 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;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AsDefaultTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AsDefaultTest.cs" />
+ </ItemGroup>
+ <Import Project="../../../../Interop.settings.targets" />
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ <ProjectReference Include="..\RefLib\RefLib.csproj" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
+
--- /dev/null
+// 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 <stdlib.h>
+#include <stdio.h>
+#include <xplatform.h>
+
+/*-----------------------------------------------------------------------------*
+* *
+* 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 <windows.h>
+
+/*-----------------------------------------------------------------------------*
+* *
+* 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
--- /dev/null
+// 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;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AsFunctionPtrTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AsFunctionPtrTest.cs" />
+ </ItemGroup>
+ <Import Project="../../../../Interop.settings.targets" />
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ <ProjectReference Include="..\RefLib\RefLib.csproj" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
--- /dev/null
+// 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;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AsInterfaceTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <!-- Test unsupported outside of windows -->
+ <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows>
+ <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AsInterfaceTest.cs" />
+ </ItemGroup>
+ <Import Project="../../../../Interop.settings.targets" />
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ <ProjectReference Include="..\RefLib\RefLib.csproj" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
+
--- /dev/null
+#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)
--- /dev/null
+// 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
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>RefLib</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="RefLib.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
--- /dev/null
+// 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<Dele>(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<Dele>(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;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AsDefaultTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AsDefaultTest.cs" />
+ </ItemGroup>
+ <Import Project="../../../../Interop.settings.targets" />
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
--- /dev/null
+// 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;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AsFunctionPtrTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AsFunctionPtrTest.cs" />
+ </ItemGroup>
+ <Import Project="../../../../Interop.settings.targets" />
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
--- /dev/null
+// 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;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AsInterfaceTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1E66554-8C8E-4141-85CF-D0CD6A0CD0B0}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <!-- Test unsupported outside of windows -->
+ <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows>
+ <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AsInterfaceTest.cs" />
+ </ItemGroup>
+ <Import Project="../../../../Interop.settings.targets" />
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CMakeLists.txt" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
+
+
+
+
+
+
--- /dev/null
+// 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 <stdio.h>
+#include <stdlib.h>
+#include <xplatform.h>
+
+/*-----------------------------------------------------------------------------*
+* *
+* 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 <windows.h>
+
+/* -----------------------------------------------------------------------------*
+* *
+* 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
--- /dev/null
+#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)