Many developers want to create wrappers for MSXML and return pointers to interfaces such as IXMLDOMDocument directly from these wrappers. This works fine except when the interface must cross execution contexts. Execution contexts are crossed whenever the wrapper and its caller exist in two different types of COM apartments, in two different processes (such as when the component is used under Microsoft Transaction Server), or on two different computers.
In order for an interface to cross execution contexts in COM, the interface must be
marshalable. COM must be able to serialize the pointer to the interface into a stream of bits that can be transferred to the other execution context.
Few people write marshaling code by hand. You can use Microsoft Interface Definition Language (MIDL) with the Microsoft IDL compiler to create marshaling code. MIDL creates the code for required proxy and stub marshaling objects when it compiles the IDL for a COM interface. IDL syntax allows interface declarations to define the attribute local, which prevents MIDL from compiling this marshaling code. This attribute is defined on all of the MSXML interfaces, as you can see by examining the MSXML.idl file that is included with Visual C++:
[
local, object,
uuid(2933BF81-7B36-11d2-B20E-00C04F983E60), // IID_IXMLDOMDocument
odl,
dual,
oleautomation,
nonextensible,
pointer_default(unique)
]
Additionally, the XML interfaces are all defined within an IDL "library" block. Interfaces must be located outside of the library block in order for MIDL to generate proxy/stub code.