6

I have a piece of code that uses Microsoft-specific extension to the C++:

interface __declspec(uuid("F614FB00-6702-11d4-B0B7-0050BABFC904"))
ICalculator : public IUnknown
{ 
    //...
};

What does this sentence expand to? How can I rewrite it with ANSI C++?

ezpresso
  • 7,896
  • 13
  • 62
  • 94

2 Answers2

6

It's not a macro so it doesn't "expand" to anything. It merely decorates the type with a given UUID in the object file metadata, which can then be extracted later with the __uuidof operator.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • Thanks! Will static member + static method like `get_uuid()` simulate the same thing? – ezpresso Jun 02 '11 at 20:41
  • @ezpresso : It could, yes, if you have the ability to change the definition of every class in question (unlike `__declspec(uuid)` which can be used non-intrusively). – ildjarn Jun 02 '11 at 20:43
5

You can also use templates (traits), if you need to statically "attach" a guid to the interface. Consider:

In a common h-file you create an empty unspecialized template:

template<typename TInterface> struct TInterfaceTraits {}

When defining your interface, write a template specialization for it (or you can write it in any other place including just before usage):

class ICalculator : public IUnknown
{ 
    //...
};
template<> struct TInterfaceTraits<class ICalculator > { 
    static GUID guid() { 
        return IID_ICalculator ; 
    } 
};

Then to get it's uuid you can write something like:

ICalculator *pCalcFace;
pObject->QueryInterface(TInterfaceTraits<ICalculator>::guid(), (void**)pCalcFace);

Of cause you can write (I leave it to you) a template wrapper to QueryInterface, which will use the traits to automatically supply proper guid, and that will be even easier to use, i.e.

ICalculator *pCalcFace = QueryInterface<ICalculator>(pObject);
Steed
  • 1,292
  • 1
  • 14
  • 33