How does the .NET COM Callable Wrapper generate IIDs?
Viewing the generated TLB file created by the CCW though the OLE/COM Object Viewer shows the IID remains constant unless I change the design of the interface (which is correct behaviour), my concern is that if I compile this same code on another machine a completely different IID will be generated despite the interface not changing and hence breaking existing COM clients.
- How are the COM Interface IDs generated by the COM Callable Wrapper?
- How does the CCW know if the interface has changed and needs to generate a new IID?
- Would it be safer to just generate my own and declare in th开发者_JAVA百科e source file?
The guid for a type is not specific to COM interop, all .NET types have a guid. You can obtain it from the Type.GUID property. The code in the CLR that generates it is available from the SSCLI20 distribution. You can have a look-see at the algorithm by checking out the code in clr/scr/vm/methodtable.cpp, MethodTable::GetGuid() method.
Summarizing the algorithm:
- if the type has the [Guid] attribute then return that
- if the type is an interface type then generate a stringized version of the interface type definition. This is done by GetStringizedItfDef() in interoputil.cpp. It starts with the fully qualified type name and appends a string version of each member definition.
- for all other types, generate a stringized version of the class. It starts with the fully qualified type name, appends the class name and appends the fully qualified assembly name.
- the resulting string is then hashed into a Guid by helper function CorGuidFromNameW().
This is enough info to answer your questions:
How are the COM Interface IDs generated by the COM Callable Wrapper?
It uses the Type.GUID as generated with the algorithm above. None of the elements in the algorithm are specific to the machine it is executed on so you don't have to fear getting different IIDs and CLSIDs on different build machines.
How does the CCW know if the interface has changed and needs to generate a new IID?
It doesn't. It purely relies on the algorithm producing different GUIDs for different interface definitions.
Would it be safer to just generate my own and declare in the source file?
Not really. There's no documented failure mode for this algorithm. Using your own [Guid] attribute significantly increases the odds that you'll forget to change it when you have to. This is a shortcut that's taken frequently and the primary source of DLL Hell. The nasty kind, the kind that makes the client crash with near-impossible to diagnose hardware exceptions. As opposed to the still-hard-but-not-impossible kind of E_NOINTERFACE. There are really only two disadvantages I can think of by relying on the auto-generated Guid: it tends to cause registry pollution on your dev machine when you forget to unregister assemblies before rebuilding them. And it slows you down a bit when you're troubleshooting COM errors because you don't readily know the guids. Admittedly, the registry pollution is good enough reason for me.
精彩评论