Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support IID on GNUC #12085

Closed
franksinankaya opened this issue Feb 21, 2019 · 9 comments
Closed

Support IID on GNUC #12085

franksinankaya opened this issue Feb 21, 2019 · 9 comments
Labels
area-PAL-coreclr question Answer questions and provide assistance, not an issue with source code or documentation.

Comments

@franksinankaya
Copy link
Contributor

I wanted to hear your opinions on this issue: microsoft/DirectXShaderCompiler#1342

GCC doesn’t support uuid but there are ways to workaround it. IMO, the simplest solution is to use typeinfo stuff from boost. But my test reveals that coreclrpal doesn’t use any external libraries and uuid stuff is heavily embedded into PAL.

Another idea is to use something like this:

#define DEFINE_UUIDOF_ID(Q, IID) struct Q; template<> GUID hold_uuidof::__IID = IID;
#define DEFINE_UUIDOF(Q, value) DEFINE_UUIDOF_ID(Q, value)
#define __uuidof(Q) hold_uuidof::__IID

DEFINE_UUIDOF(IUnknown, "00000000-0000-0000-C000-000000000046")
class IUnknown
{
uint32_t my_member;
};

and adjust MIDL_INTERFACE to take a class parameter.

MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
IUnknown
{
uint32_t my_member;
};

would be

MIDL_INTERFACE(IUnknown, "00000000-0000-0000-C000-000000000046")
IUnknown
{
uint32_t my_member;
};

This still doesn't solve DECLSPEC_UUID.

@franksinankaya
Copy link
Contributor Author

@janvorli @jkotas @am11

@jkotas
Copy link
Member

jkotas commented Feb 21, 2019

CoreCLR uses the old fashioned portable way to define GUIDs that was used before the __uuidof Microsoft C++ extension was invented.

The GUIDs are initialized by compiling the *_i.cpp files generated by MIDL compiler: https://github.com/dotnet/coreclr/blob/master/src/inc/CMakeLists.txt#L54

adjust MIDL_INTERFACE to take a class parameter.

MIDL_INTERFACE is a macro from Windows SDK headers that is used in auto-generated code. We would not want to change its shape.

@franksinankaya
Copy link
Contributor Author

franksinankaya commented Feb 26, 2019

Another approach is to stub out MIDL_INTERFACE as

#define MIDL_INTERFACE(x) struct

Then,

__uuidof() needs to be something like

#define __uuidof(T) boost::typeindex::type_index(typeid(T))

or

#define __uuidof(T) std::type_index(typeid(T))

Since code is compiled with -nostdinc, what's the best way to implement this?

@am11
Copy link
Member

am11 commented Feb 26, 2019

@janvorli, did the portable GUID implementation prior to v2.1 release, and removed the build-time and runtime dependencies on libuuid: dotnet/coreclr#16643. Could it be used with MIDL_INTERFACE?

@janvorli
Copy link
Member

@am11 we don't want to add more external library dependencies again. But I am not sure how the libuuid would help anyways. All it implements is generating uuids, converting between strings and uuids, and comparing uuids.

@am11
Copy link
Member

am11 commented Feb 26, 2019

Could it be used with MIDL_INTERFACE?

sorry by it I meant could the PAL_Random or CoCreateGuid be used in case of MIDL_INTERFACE, not bringing back libuuid :)

@janvorli
Copy link
Member

We don't need to create new guids. The guids are defined on the interfaces and have specific predefined values that external things like profiler or debugger depend on.
What we need here is to attach those guids to interfaces so that we can query a guid for a given interface.

@franksinankaya I am not sure how you envision a technique using the type_index would work. At many places, we are comparing some IID constant / variable to the __uuidof(type). So it seems you'd need to have some dynamic lookup of type_index to IID in addition to what you've suggested. Then you'd need to fill it in with all known interfaces / IIDs.

It seems we cannot avoid explicitly creating a mapping between all interfaces and their respective IIDs, but I think we can do that statically. Here is my idea:

class TypeToIID
{
public:
    // Default version of the GetIID function for types where the type was not bound to IID using the macro below
    template<typename TInterface>
    static IID GetIID()
    {
        return IID_NULL;
    }
};

#define BIND_UUID_OF(T) template<> IID TypeToIID::GetIID<T>() { return IID_##T; }
#define __uuidof(T) TypeToIID::GetIID<T>()

// For each known interface, we would then need to use the BIND_UUID_OF, as follows:
BIND_UUID_OF(IUnknown)
BIND_UUID_OF(ICLRPrivAssembly)
BIND_UUID_OF(ICLRServices)
// etc...

@jkotas
Copy link
Member

jkotas commented Feb 26, 2019

Yes, that should work. @franksinankaya Feel free to use it in your project, but I do not think we would want to complicate CoreCLR PAL with this.

@jkotas jkotas closed this as completed Feb 26, 2019
@franksinankaya
Copy link
Contributor Author

I have started implementing this. Writing an explicit BIND_UUID_OF seemed excessive and unscaling. I think the right solution is to add BIND_UUID_OF to DEFINE_GUID in guiddef.h so that the template also gets instantiated anytime a new GUID is declared.

Issue is that DEFINE_GUID is called with IID_xyz pattern.

I need to convert it to BIND_UUID_OF(xyz)

Is this possible at all? I was looking at constexpr.

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-PAL-coreclr question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests

4 participants