Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -1138,12 +1138,15 @@ class MethodTable
{
LIMITED_METHOD_DAC_CONTRACT;

// All ComObjects except for __ComObject
// have dynamic Interface maps
return GetNumInterfaces() > 0
&& IsComObjectType()
&& !ParentEquals(g_pObjectClass)
&& this != g_pBaseCOMObject;
// All ComObjects except for __ComObject have dynamic Interface maps
// to avoid costly QIs on required managed interfaces. The __ComObject
// type is inserted automatically when a COM object enters the runtime.
// For example, an incoming COM interface pointer or activation via a
// COM coclass. See ComObject::SupportsInterface() for relevant use of
// the dynamic interface map.
return IsComObjectType()
&& GetNumInterfaces() > g_pBaseCOMObject->GetNumInterfaces()
&& !ParentEquals(g_pObjectClass);
}
#endif // FEATURE_COMINTEROP

Expand Down
6 changes: 4 additions & 2 deletions src/tests/Interop/COM/NETClients/MiscTypes/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static int TestEntryPoint()
return 100;
}

private class InterfaceImpl : Server.Contract.IInterface2
private class InterfaceImpl : Server.Contract.IInterface1
{
}

Expand Down Expand Up @@ -214,9 +214,11 @@ private static void ValidationTests()

Console.WriteLine("-- Interfaces...");
{
Assert.True(new MiscTypesTestingClass() is Server.Contract.IInterface1);
Assert.True(Activator.CreateInstance(typeof(MiscTypesTestingClass)) is Server.Contract.IInterface1);

var interfaceMaybe = miscTypeTesting.Marshal_Interface(new InterfaceImpl());
Assert.True(interfaceMaybe is Server.Contract.IInterface1);
Assert.True(interfaceMaybe is Server.Contract.IInterface2);
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/tests/Interop/COM/NativeClients/MiscTypes/MiscTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,15 @@ struct VariantMarshalTest

class InterfaceImpl :
public UnknownImpl,
public IInterface2
public IInterface1
{
public: // IInterface1
public: // IInterface2
public: // IUnknown
STDMETHOD(QueryInterface)(
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
return DoQueryInterface(riid, ppvObject, static_cast<IInterface1 *>(this), static_cast<IInterface2 *>(this));
return DoQueryInterface(riid, ppvObject, static_cast<IInterface1 *>(this));
}

DEFINE_REF_COUNTING();
Expand Down Expand Up @@ -354,7 +353,7 @@ void ValidationTests()
ComSmartPtr<InterfaceImpl> iface;
iface.Attach(new InterfaceImpl());

ComSmartPtr<IInterface2> result;
ComSmartPtr<IInterface1> result;
HRESULT hr = miscTypesTesting->Marshal_Interface(iface, &result);
THROW_IF_FAILED(hr);
}
Expand Down
18 changes: 9 additions & 9 deletions src/tests/Interop/COM/NativeServer/MiscTypesTesting.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
#include <xplatform.h>
#include "Servers.h"

class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting
class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting, public IInterface1
{
struct InterfaceImpl : public UnknownImpl, public IInterface2
struct InterfaceImpl : public UnknownImpl, public IInterface1
{
public: // IInterface1
public: // IInterface2
public: // IUnknown
STDMETHOD(QueryInterface)(
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
return DoQueryInterface(riid, ppvObject, static_cast<IInterface1 *>(this), static_cast<IInterface2 *>(this));
return DoQueryInterface(riid, ppvObject, static_cast<IInterface1 *>(this));
}

DEFINE_REF_COUNTING();
};
public: // IInterface1
public: // IMiscTypesTesting
DEF_FUNC(Marshal_Variant)(_In_ VARIANT obj, _Out_ VARIANT* result)
{
Expand All @@ -38,18 +38,18 @@ class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting
return E_NOTIMPL;
}

DEF_FUNC(Marshal_Interface)(_In_ IUnknown* input, _Outptr_ IInterface2** value)
DEF_FUNC(Marshal_Interface)(_In_ IUnknown* input, _Outptr_ IInterface1** value)
{
HRESULT hr;

IInterface2* ifaceMaybe = nullptr;
hr = input->QueryInterface(__uuidof(IInterface2), (void**)&ifaceMaybe);
IInterface1* ifaceMaybe = nullptr;
hr = input->QueryInterface(__uuidof(IInterface1), (void**)&ifaceMaybe);
if (FAILED(hr))
return hr;
(void)ifaceMaybe->Release();

InterfaceImpl* inst = new InterfaceImpl();
hr = inst->QueryInterface(__uuidof(IInterface2), (void**)value);
hr = inst->QueryInterface(__uuidof(IInterface1), (void**)value);
(void)inst->Release();
return hr;
}
Expand All @@ -59,7 +59,7 @@ class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
return DoQueryInterface(riid, ppvObject, static_cast<IMiscTypesTesting *>(this));
return DoQueryInterface(riid, ppvObject, static_cast<IMiscTypesTesting *>(this), static_cast<IInterface1 *>(this));
}

DEFINE_REF_COUNTING();
Expand Down
13 changes: 6 additions & 7 deletions src/tests/Interop/COM/ServerContracts/Server.Contracts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,17 +184,16 @@ string Add_BStr(
void Pass_Through_LCID(out int lcid);
}

[ComVisible(true)]
[Guid("4242A2F9-995D-4302-A722-02058CF58158")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInterface1
// This interface must not be an explicit COM interface to trigger
// the dynamic interface map codepath in ComObject.
public interface Interface0
{
}

[ComVisible(true)]
[Guid("7AC820FE-E227-4C4D-A8B0-FCA68C459B43")]
[Guid("4242A2F9-995D-4302-A722-02058CF58158")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInterface2 : IInterface1
public interface IInterface1 : Interface0
{
}

Expand All @@ -211,7 +210,7 @@ public interface IMiscTypesTesting
void Marshal_ByRefVariant(ref object result, object value);

[return: MarshalAs(UnmanagedType.Interface)]
IInterface2 Marshal_Interface([MarshalAs(UnmanagedType.Interface)] object inst);
IInterface1 Marshal_Interface([MarshalAs(UnmanagedType.Interface)] object inst);
}

public struct HResult
Expand Down
7 changes: 1 addition & 6 deletions src/tests/Interop/COM/ServerContracts/Server.Contracts.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,6 @@ IInterface1 : IUnknown
{
};

struct __declspec(uuid("7AC820FE-E227-4C4D-A8B0-FCA68C459B43"))
IInterface2 : public IInterface1
{
};

struct __declspec(uuid("7FBB8677-BDD0-4E5A-B38B-CA92A4555466"))
IMiscTypesTesting : IUnknown
{
Expand All @@ -393,7 +388,7 @@ IMiscTypesTesting : IUnknown

virtual HRESULT STDMETHODCALLTYPE Marshal_Interface (
/*[in]*/ IUnknown* value,
/*[out,ret]*/ IInterface2** iface) = 0;
/*[out,ret]*/ IInterface1** iface) = 0;
};

struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556"))
Expand Down
Loading