Cross Platform GUID Association With Types - Vladimir Morozov
Cross Platform GUID Association With Types - Vladimir Morozov
Vladimir Morozov
Microsoft
9/12/2014
Why do we need GUIDs for types?
• To implement IUnknown::QueryInterface
• In Office we do not use RTTI
• IUnknown::QueryInterface is used for dynamic cast
• Used by a lot of code in Office and COM in general
• Visual C++ has native support for GUIDs
• To specify GUID:
__declspec(uuid(“38a24b6a-91d3-499e-9e4a-5cc6fc647331”))
• To get GUID for a type: __uuidof(IWidget)
• No support in C++ Standard
Typical cross platform GUID association
struct __declspec(uuid("4D675322-F6F5-4E85-94EF-2927DFAA1409"))
IWorkerCallback : IUnknown
{
virtual void Invoke(IWorkerObject* pObj) = 0;
};
#ifdef __clang__
// cannot specialize template in a different namespace
}} // namespace Mso::Async
guid_of<Mso::Async::IWorkerCallback>::value =
{ 0x4D675322, 0xF6F5, 0x4E85, { 0x94, 0xEF, 0x29, 0x27, 0xDF, 0xAA, 0x14, 0x09 } };
But…
• Not a Standard C++
• Works only in Visual C++
• Increases instance size by a pointer size
• Do not use it!
Macro to the rescue!
STRUCT_GUID(IWorkerCallback, "4D675322-F6F5-4E85-94EF-2927DFAA1409")
struct IWorkerCallback : IUnknown
{
virtual void Invoke(IWorkerObject* pObj) = 0;
};
• Implementation is trivial
• __declspec(uuid) can be applied anywhere: type
declaration, forward declaration, or redeclaration
Implementation for Clang
STRUCT_GUID is expanded to get_guid () function definition
#define STRUCT_GUID(type, guidString) \
struct type; \
extern "C++" \
constexpr GUID get_guid(type*) noexcept { return str_to_guid(guidString); }