summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jkoritzinsky@gmail.com>2019-04-04 22:56:56 -0700
committerGitHub <noreply@github.com>2019-04-04 22:56:56 -0700
commit8241971dc93dca98992596a9396dee1a2031ea15 (patch)
treeac75247a13082544183134f946ecd185d00a4dd2
parent3a058450784d6ceb2ca8fd4b7b1ca8d3d6d4e8a9 (diff)
downloadcoreclr-8241971dc93dca98992596a9396dee1a2031ea15.tar.gz
coreclr-8241971dc93dca98992596a9396dee1a2031ea15.tar.bz2
coreclr-8241971dc93dca98992596a9396dee1a2031ea15.zip
Disable marshalling delegates as _Delegate and enable marshalling delegates as IDispatch. (#23738)
* Disable marshalling delegates as _Delegate and enable marshalling delegates as IDispatch. * ifdef out the new IDispatch marshalling on non-COM-supporting platforms. * PR feedback.
-rw-r--r--src/dlls/mscorrc/mscorrc.rc3
-rw-r--r--src/dlls/mscorrc/resource.h1
-rw-r--r--src/vm/fieldmarshaler.cpp16
-rw-r--r--src/vm/mlinfo.cpp39
-rw-r--r--tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp58
-rw-r--r--tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs10
-rw-r--r--tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs43
-rw-r--r--tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp70
8 files changed, 143 insertions, 97 deletions
diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc
index 4853f00789..7acfb09ecb 100644
--- a/src/dlls/mscorrc/mscorrc.rc
+++ b/src/dlls/mscorrc/mscorrc.rc
@@ -586,7 +586,8 @@ BEGIN
IDS_EE_BADMARSHAL_R8 "Invalid managed/unmanaged type combination (Double must be paired with R8)."
IDS_EE_BADMARSHAL_PTR "Invalid managed/unmanaged type combination (pointers must not have a MarshalAs attribute set)."
IDS_EE_BADMARSHAL_NOLAYOUT "The type definition of this type has no layout information."
- IDS_EE_BADMARSHAL_DELEGATE "Invalid managed/unmanaged type combination (Delegates must be paired with FunctionPtr or Interface)."
+ IDS_EE_BADMARSHAL_DELEGATE "Invalid managed/unmanaged type combination (Delegates must be paired with FunctionPtr or IDispatch)."
+ IDS_EE_BADMARSHAL_DELEGATE_TLB_INTERFACE ".NET Core does not support marshalling delegates to the _Delegate interface provided by the .NET Framework COM Type Library. To marshal a delegate as an interface, marshal it as an IDispatch pointer."
IDS_EE_BADMARSHAL_FNPTR "Invalid managed/unmanaged type combination (function pointers must be paired with FunctionPtr)."
IDS_EE_BADMARSHAL_INTERFACE "Invalid managed/unmanaged type combination (Interfaces must be paired with Interface)."
IDS_EE_BADMARSHAL_CLASS "Invalid managed/unmanaged type combination (this type must be paired with LPStruct or Interface)."
diff --git a/src/dlls/mscorrc/resource.h b/src/dlls/mscorrc/resource.h
index 609a31d253..cc9e0e81f5 100644
--- a/src/dlls/mscorrc/resource.h
+++ b/src/dlls/mscorrc/resource.h
@@ -721,3 +721,4 @@
#define IDS_EE_BADMARSHAL_STRING_OUT 0x2646
#define IDS_EE_BADMARSHAL_COPYCTORRESTRICTION 0x2647
#define IDS_EE_BADMARSHAL_WINRT_COPYCTOR 0x2648
+#define IDS_EE_BADMARSHAL_DELEGATE_TLB_INTERFACE 0x2649
diff --git a/src/vm/fieldmarshaler.cpp b/src/vm/fieldmarshaler.cpp
index 51d9b8b798..a8676d65bd 100644
--- a/src/vm/fieldmarshaler.cpp
+++ b/src/vm/fieldmarshaler.cpp
@@ -588,12 +588,16 @@ do \
{
INITFIELDMARSHALER(NFT_ILLEGAL, FieldMarshaler_Illegal, (IDS_EE_BADMARSHAL_WINRT_ILLEGAL_TYPE));
}
+ else if (COMDelegate::IsDelegate(thNestedType.GetMethodTable()))
+ {
+ INITFIELDMARSHALER(NFT_ILLEGAL, FieldMarshaler_Illegal, (IDS_EE_BADMARSHAL_DELEGATE_TLB_INTERFACE));
+ }
else
{
ItfMarshalInfo itfInfo;
if (FAILED(MarshalInfo::TryGetItfMarshalInfo(thNestedType, FALSE, FALSE, &itfInfo)))
break;
-
+
INITFIELDMARSHALER(NFT_INTERFACE, FieldMarshaler_Interface, (itfInfo.thClass.GetMethodTable(), itfInfo.thItf.GetMethodTable(), itfInfo.dwFlags));
}
}
@@ -792,6 +796,16 @@ do \
{
INITFIELDMARSHALER(NFT_DELEGATE, FieldMarshaler_Delegate, (thNestedType.GetMethodTable()));
}
+#ifdef FEATURE_COMINTEROP
+ else if (ntype == NATIVE_TYPE_IDISPATCH)
+ {
+ ItfMarshalInfo itfInfo;
+ if (FAILED(MarshalInfo::TryGetItfMarshalInfo(thNestedType, FALSE, FALSE, &itfInfo)))
+ break;
+
+ INITFIELDMARSHALER(NFT_INTERFACE, FieldMarshaler_Interface, (itfInfo.thClass.GetMethodTable(), itfInfo.thItf.GetMethodTable(), itfInfo.dwFlags));
+ }
+#endif // FEATURE_COMINTEROP
else
{
INITFIELDMARSHALER(NFT_ILLEGAL, FieldMarshaler_Illegal, (IDS_EE_BADMARSHAL_DELEGATE));
diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp
index f861c43cf8..cb512bb4f0 100644
--- a/src/vm/mlinfo.cpp
+++ b/src/vm/mlinfo.cpp
@@ -2003,16 +2003,27 @@ MarshalInfo::MarshalInfo(Module* pModule,
IfFailGoto(E_FAIL, lFail);
}
- if (m_ms == MARSHAL_SCENARIO_WINRT && COMDelegate::IsDelegate(m_pMT))
+ if (COMDelegate::IsDelegate(m_pMT))
{
- // In WinRT scenarios delegates must be WinRT delegates
- if (!m_pMT->IsProjectedFromWinRT() && !WinRTTypeNameConverter::IsRedirectedType(m_pMT))
+ if (m_ms == MARSHAL_SCENARIO_WINRT)
{
- m_resID = IDS_EE_BADMARSHAL_WINRT_DELEGATE;
+ // In WinRT scenarios delegates must be WinRT delegates
+ if (!m_pMT->IsProjectedFromWinRT() && !WinRTTypeNameConverter::IsRedirectedType(m_pMT))
+ {
+ m_resID = IDS_EE_BADMARSHAL_WINRT_DELEGATE;
+ IfFailGoto(E_FAIL, lFail);
+ }
+ }
+ else
+ {
+ // UnmanagedType.Interface for delegates used to mean the .NET Framework _Delegate interface.
+ // We don't support that interface in .NET Core, so we disallow marshalling as it here.
+ // The user can specify UnmanagedType.IDispatch and use the delegate through the IDispatch interface
+ // if they need an interface pointer.
+ m_resID = IDS_EE_BADMARSHAL_DELEGATE_TLB_INTERFACE;
IfFailGoto(E_FAIL, lFail);
}
}
-
m_type = MARSHAL_TYPE_INTERFACE;
}
else if (pDefaultMT != NULL && nativeType == NATIVE_TYPE_DEFAULT)
@@ -2291,17 +2302,29 @@ MarshalInfo::MarshalInfo(Module* pModule,
case NATIVE_TYPE_DEFAULT:
#ifdef FEATURE_COMINTEROP
- if (m_ms != MARSHAL_SCENARIO_NDIRECT)
+ if (m_ms == MARSHAL_SCENARIO_WINRT)
{
- _ASSERTE(m_ms == MARSHAL_SCENARIO_COMINTEROP || m_ms == MARSHAL_SCENARIO_WINRT);
m_type = MARSHAL_TYPE_INTERFACE;
}
+ else if (m_ms == MARSHAL_SCENARIO_COMINTEROP)
+ {
+ // Default for COM marshalling for delegates used to mean the .NET Framework _Delegate interface.
+ // We don't support that interface in .NET Core, so we disallow marshalling as it here.
+ // The user can specify UnmanagedType.IDispatch and use the delegate through the IDispatch interface
+ // if they need an interface pointer.
+ m_resID = IDS_EE_BADMARSHAL_DELEGATE_TLB_INTERFACE;
+ IfFailGoto(E_FAIL, lFail);
+ }
else
#endif // FEATURE_COMINTEROP
m_type = MARSHAL_TYPE_DELEGATE;
break;
-
+#ifdef FEATURE_COMINTEROP
+ case NATIVE_TYPE_IDISPATCH:
+ m_type = MARSHAL_TYPE_INTERFACE;
+ break;
+#endif
default:
m_resID = IDS_EE_BADMARSHAL_DELEGATE;
IfFailGoto(E_FAIL, lFail);
diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp
index d5fdf86b55..9f43d63a0d 100644
--- a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp
+++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/AsFieldNative.cpp
@@ -113,9 +113,6 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE TakeDelegateAsFieldInClass_Exp(Clas
* For MarshalDelegateAsField_AsInterface.cs *
* *
*-----------------------------------------------------------------------------*/
-
-#import "mscorlib.tlb" no_namespace named_guids raw_interfaces_only rename("ReportEvent","ReportEventNew")
-
typedef struct{
int result1;
int result2;
@@ -167,7 +164,7 @@ bool STDMETHODCALLTYPE Verify(Result expectedR, Result resultR)
typedef struct _Struct3_InterfacePtrAsField1_Seq{
BOOL verification;
- _Delegate * p_dele;
+ IDispatch * p_dele;
}Struct3_InterfacePtrAsField1_Seq;
extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Seq(Struct3_InterfacePtrAsField1_Seq sis)
@@ -183,14 +180,6 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Seq
}
else
{
- hr = sis.p_dele->DynamicInvoke( NULL, NULL);
- if(FAILED(hr))
- {
- return FALSE;
- }
- bool tempBool = sis.verification && Verify( expected, result);
-
-
//IDispatch::Invoke
ResetToZero();
@@ -234,14 +223,14 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Seq
return FALSE;
}
- return tempBool && Verify(expected, result);
+ return Verify(expected, result);
}
}
typedef struct _Struct3_InterfacePtrAsField2_Exp{
bool verification;
int Padding;
- _Delegate * p_dele;
+ IDispatch * p_dele;
}Struct3_InterfacePtrAsField2_Exp;
extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Exp(Struct3_InterfacePtrAsField2_Exp sie)
@@ -255,18 +244,9 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Exp
printf("NULL field member.\n");
return FALSE;
}
- else
+ 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");
@@ -307,7 +287,7 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInStruct_Exp
return FALSE;
}
- return tempBool && Verify(expected, result);
+ return Verify(expected, result);
}
}
@@ -315,7 +295,7 @@ class Class3_InterfacePtrAsField3_Seq
{
public:
bool verification;
- _Delegate * p_dele;
+ IDispatch * p_dele;
};
extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Seq(Class3_InterfacePtrAsField3_Seq *cis)
@@ -331,14 +311,6 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Seq(
}
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");
@@ -380,7 +352,7 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Seq(
return FALSE;
}
- return tempBool && Verify(expected, result);
+ return Verify(expected, result);
}
}
@@ -389,7 +361,7 @@ class Class3_InterfacePtrAsField4_Exp{
public:
bool verification;
int Padding;
- _Delegate * p_dele;
+ IDispatch * p_dele;
};
extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Exp(Class3_InterfacePtrAsField4_Exp *cie)
@@ -405,14 +377,6 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Exp(
}
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");
@@ -453,7 +417,11 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrAsFieldInClass_Exp(
return FALSE;
}
- return tempBool && Verify(expected, result);
+ return Verify(expected, result);
}
}
+
+extern "C" DLL_EXPORT void STDMETHODCALLTYPE TakeDelegateAsInterface(void* illegal)
+{
+}
#endif
diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs
index a89be582b3..37f74c9c87 100644
--- a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs
+++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsField/RefLib/RefLib.cs
@@ -107,7 +107,7 @@ public struct Struct3_InterfacePtrAsField1_Seq
{
public bool verification;
- [MarshalAs(UnmanagedType.Interface)]
+ [MarshalAs(UnmanagedType.IDispatch)]
public Dele2 dele;
}
@@ -121,7 +121,7 @@ public struct Struct3_InterfacePtrAsField2_Exp
public Int32 Padding;
[FieldOffset(8)]
- [MarshalAs(UnmanagedType.Interface)]
+ [MarshalAs(UnmanagedType.IDispatch)]
public Dele2 dele;
}
@@ -130,7 +130,7 @@ public class Class3_InterfacePtrAsField3_Seq
{
public bool verification;
- [MarshalAs(UnmanagedType.Interface)]
+ [MarshalAs(UnmanagedType.IDispatch)]
public Dele2 dele;
}
@@ -144,7 +144,7 @@ public class Class3_InterfacePtrAsField4_Exp
public Int32 Padding;
[FieldOffset(8)]
- [MarshalAs(UnmanagedType.Interface)]
+ [MarshalAs(UnmanagedType.IDispatch)]
public Dele2 dele;
}
-#endregion \ No newline at end of file
+#endregion
diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs
index b06260bf79..7e43687511 100644
--- a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs
+++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsInterface/AsInterfaceTest.cs
@@ -11,32 +11,35 @@ class AsInterfaceTest
public delegate void Dele();
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByValParam([MarshalAs(UnmanagedType.Interface)] Dele dele);
+ extern static bool Take_DelegatePtrByValParam([MarshalAs(UnmanagedType.IDispatch)] Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByRefParam([MarshalAs(UnmanagedType.Interface)] ref Dele dele);
+ extern static bool Take_DelegatePtrByRefParam([MarshalAs(UnmanagedType.IDispatch)] ref Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByInValParam([In, MarshalAs(UnmanagedType.Interface)] Dele dele);
+ extern static bool Take_DelegatePtrByInValParam([In, MarshalAs(UnmanagedType.IDispatch)] Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByInRefParam([In, MarshalAs(UnmanagedType.Interface)] ref Dele dele);
+ extern static bool Take_DelegatePtrByInRefParam([In, MarshalAs(UnmanagedType.IDispatch)] ref Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByOutValParam([Out, MarshalAs(UnmanagedType.Interface)] Dele dele);
+ extern static bool Take_DelegatePtrByOutValParam([Out, MarshalAs(UnmanagedType.IDispatch)] Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByOutRefParam([Out, MarshalAs(UnmanagedType.Interface)]out Dele dele, [MarshalAs(UnmanagedType.Interface)] Dele deleHelper);
+ extern static bool Take_DelegatePtrByOutRefParam([Out, MarshalAs(UnmanagedType.IDispatch)]out Dele dele, [MarshalAs(UnmanagedType.IDispatch)] Dele deleHelper);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByInOutValParam([In, Out, MarshalAs(UnmanagedType.Interface)] Dele dele);
+ extern static bool Take_DelegatePtrByInOutValParam([In, Out, MarshalAs(UnmanagedType.IDispatch)] Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- extern static bool Take_DelegatePtrByInOutRefParam([In, Out, MarshalAs(UnmanagedType.Interface)] ref Dele dele);
+ extern static bool Take_DelegatePtrByInOutRefParam([In, Out, MarshalAs(UnmanagedType.IDispatch)] ref Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
- [return: MarshalAs(UnmanagedType.Interface)]
- extern static Dele ReturnDelegatePtrByVal([MarshalAs(UnmanagedType.Interface)] Dele dele);
+ [return: MarshalAs(UnmanagedType.IDispatch)]
+ extern static Dele ReturnDelegatePtrByVal([MarshalAs(UnmanagedType.IDispatch)] Dele dele);
+
+ [DllImport("PInvoke_Delegate_AsParam")]
+ extern static void TakeDelegateAsInterface([MarshalAs(UnmanagedType.Interface)] Dele dele);
[DllImport("PInvoke_Delegate_AsParam")]
extern static int RetFieldResult1();
@@ -63,40 +66,40 @@ class AsInterfaceTest
static int Main()
{
try{
- Console.WriteLine("Scenario 1 : Delegate marshaled by val with attribute [MarshalAs(UnmanagedType.Interface)].");
+ Console.WriteLine("Scenario 1 : Delegate marshaled by val with attribute [MarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 2 : Delegate marshaled by ref with attribute [MarshalAs(MarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 3 : Delegate marshaled by val with attribute [In,MarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 4 : Delegate marshaled by ref with attribute [In,MarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 5 : Delegate marshaled by val with attribute [Out,MarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 6 : Delegate marshaled by ref with attribute [Out,MarshalAs(UnmanagedType.IDispatch)].");
Dele dele6 = null;
Dele deleHelper = new Dele(CommonMethod1);
deleHelper += CommonMethod2;
@@ -105,20 +108,20 @@ class AsInterfaceTest
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)].");
+ Console.WriteLine("\n\nScenario 7 : Delegate marshaled by val with attribute [In,OutMarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 8 : Delegate marshaled by ref with attribute [In,OutMarshalAs(MarshalAs(UnmanagedType.IDispatch)].");
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)].");
+ Console.WriteLine("\n\nScenario 9 : return Delegate marshaled by val with attribute [return:MarshalAs(UnmanagedType.IDispatch)].");
Dele dele9 = new Dele(CommonMethod1);
dele9 += CommonMethod2;
dele9 += CommonMethod3;
@@ -128,6 +131,8 @@ class AsInterfaceTest
Assert.AreEqual(COMMONMETHOD2_RESULT, RetFieldResult2(), "RetFieldResult2() return value is wrong");
Assert.AreEqual(COMMONMETHOD3_RESULT, RetFieldResult3(), "RetFieldResult3() return value is wrong");
+ Assert.Throws<MarshalDirectiveException>(() => TakeDelegateAsInterface(new Dele(CommonMethod1)));
+
return 100;
} catch (Exception e){
Console.WriteLine($"Test Failure: {e}");
diff --git a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp
index d85babb923..c3f2084b3c 100644
--- a/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp
+++ b/tests/src/Interop/PInvoke/Delegate/MarshalDelegateAsParam/AsParamNative.cpp
@@ -240,8 +240,6 @@ extern "C" DLL_EXPORT DelegateParam STDMETHODCALLTYPE ReturnDelegateByVal()
* *
* -----------------------------------------------------------------------------*/
-#import "mscorlib.tlb" no_namespace named_guids raw_interfaces_only rename("ReportEvent","ReportEventNew")
-
typedef struct{
int result1;
int result2;
@@ -290,24 +288,60 @@ BOOL STDMETHODCALLTYPE Verify(Result expectedR, Result resultR)
&& expectedR.result3 == resultR.result3;
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByValParam(_Delegate * p_dele)
+HRESULT InvokeDelegate(IDispatch* dele)
+{
+ HRESULT hr;
+ BSTR bstrNames[1];
+ bstrNames[0] = SysAllocString(L"DynamicInvoke");
+ DISPID dispid = 0;
+ hr = 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 hr;
+ }
+
+ DISPPARAMS params = { NULL, NULL, 0, 0 };
+
+ hr = dele->Invoke(
+ dispid,
+ IID_NULL,
+ GetUserDefaultLCID(),
+ DISPATCH_METHOD,
+ &params,
+ NULL,
+ NULL,
+ NULL);
+
+ return hr;
+}
+
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByValParam(IDispatch * p_dele)
{
ResetToZero();
HRESULT hr;
- hr = p_dele->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(p_dele);
if(FAILED(hr))
return FALSE;
else
return Verify(expected, result);
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByRefParam(_Delegate **pp_dele)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByRefParam(IDispatch **pp_dele)
{
ResetToZero();
HRESULT hr;
- hr = (*pp_dele)->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(*pp_dele);
if(FAILED(hr))
{
return FALSE;
@@ -319,12 +353,12 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByRefParam(_Delegat
}
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInValParam(_Delegate * p_dele)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInValParam(IDispatch * p_dele)
{
ResetToZero();
HRESULT hr;
- hr = p_dele->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(p_dele);
if(FAILED(hr))
{
return FALSE;
@@ -335,12 +369,12 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInValParam(_Deleg
}
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInRefParam(_Delegate **pp_dele)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInRefParam(IDispatch **pp_dele)
{
ResetToZero();
HRESULT hr;
- hr = (*pp_dele)->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(*pp_dele);
if(FAILED(hr))
{
return FALSE;
@@ -352,12 +386,12 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInRefParam(_Deleg
}
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutValParam(_Delegate * p_dele)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutValParam(IDispatch * p_dele)
{
ResetToZero();
HRESULT hr;
- hr = p_dele->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(p_dele);
if(FAILED(hr))
{
return FALSE;
@@ -385,7 +419,7 @@ extern "C" DLL_EXPORT int STDMETHODCALLTYPE RetFieldResult3()
return result.result3;
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutRefParam(_Delegate ** pp_dele, _Delegate * pdeleHelper)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutRefParam(IDispatch ** pp_dele, IDispatch * pdeleHelper)
{
printf("In Take_DelegatePtrByOutRefParam native side \n");
ResetToZero();
@@ -402,12 +436,12 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByOutRefParam(_Dele
}
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutValParam(_Delegate * p_dele)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutValParam(IDispatch * p_dele)
{
ResetToZero();
HRESULT hr;
- hr = p_dele->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(p_dele);
if(FAILED(hr))
{
return FALSE;
@@ -418,12 +452,12 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutValParam(_De
}
}
-extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutRefParam(_Delegate **pp_dele)
+extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutRefParam(IDispatch **pp_dele)
{
ResetToZero();
HRESULT hr;
- hr = (*pp_dele)->DynamicInvoke(NULL, NULL);
+ hr = InvokeDelegate(*pp_dele);
if(FAILED(hr))
{
return FALSE;
@@ -435,7 +469,7 @@ extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Take_DelegatePtrByInOutRefParam(_De
}
}
-extern "C" DLL_EXPORT _Delegate* ReturnDelegatePtrByVal(_Delegate * pdeleHelper)
+extern "C" DLL_EXPORT IDispatch* ReturnDelegatePtrByVal(IDispatch * pdeleHelper)
{
pdeleHelper->AddRef();
return pdeleHelper;