IDL files serve two (and only two) purposes only:
An IDL file is typically divided into two parts:
// IDL: library block requires only the uuid attribute
[
uuid(A8A71511-D4B8-11D4-8053-00D0B79F36F8),
version( 1.0 )
]
library AtomLib
{
// Interfaces inside the library block should have
[oleuatomation] (or [dual] for IDispatch interfaces)
// attributes to enable the Universal Marshaler
[
uuid(51C3382C-D4D1-11d4-8053-00D0B79F36F8),
oleautomation,
...
]
interface IAtom : IUnknown
{
...
}
...
};
Interfaces whose methods require data types that are not automation compatible must be declared outside the library block and run with the /Oicf MIDL compiler switch (in VC++, this equivalent to checking the stubl-ess Proxies check box in the MIDL tab of Project Settings). Therefore, declare an interface outside the library block only if its methods deal with non-automation compatible data types. This means that proxy/stub DLL must be built and registered.
Interfaces declared outside the library block will not appear in the type library. No interface information will be available to development environments like VB. To force
an interface defined outside the library block to appear in the type library, add a
reference to it in the library section.
// IDL: Forcing an 'outside the library block' interface to appear in the type library
[ ... ]
interface INeutron : IUnknown
{
...
};
[ ... ]
library AtomLib
{
...
interface INeutron; // Reference to INeutron
[
oleautomation,
...
]
interface IAtom : IUnknown
{
oleautomation,
...
}
...
};
The following table summarizes interface location and interaction with oleautomation:
Interface location | [oleautomation]/ [dual] defined | [oleautomation] / [dual] not defined |
---|---|---|
Inside library block |
|
|
Outside library block |
|
|
// IDL: using import within interface definitions
[ ... ]
interface INeutron : IUnknown
{
import "atom.idl";
HRESULT AddAtom( [in] IAtom* pAtom );
};
[ ... ]
interface IElectorn : IUnknown
{
import "atom.idl";
HRESULT AddAtom( [in] IAtom* pAtom );
};
/******************************************************************
Structure of a model IDL file
******************************************************************/
// Use 'import' to bring in data types defined in external files
import "oaidl.idl";
import "ocidl.idl";
/*******************************************************************
Outside the library block. Interfaces will use Proxy/Stub DLL as
long as /Oicf MIDL flag is defined. No type library information will
be generated, unless the interface is referenced in the library block .
*******************************************************************/
[
uuid(51C3382C-D4D1-11d4-8053-00D0B79F36F9),
object,
helpstring("Some meaningful description please"),
pointer_default(unique)
]
interface INeutorn : IUnknown
{
// Use 'import' to import externally-defined types used by this interface
import "atom.idl"
HRESULT AddAtom( [in] IAtom* pAtom );
};
[
uuid(51C3382C-D4D1-11d4-8053-00D0B79F36FA),
object,
helpstring("Another meaningful description please"),
pointer_default(unique)
]
interface IPositron : IUnknown
{
// Use 'import' to import externally-defined types used by this interface
import "atom.idl"
HRESULT RemoveAtom( [in] IAtom* pAtom );
};
/**************************************************************************
Library block. MIDL will generate a .tlb file. If registered, IAtom will be
marshaled with the Universal Marshaler. Development tools can also query for
capabilities of the component.
Recall that 'import' statements should not be placed in the library block
**************************************************************************/
[
uuid(A8A71511-D4B8-11D4-8053-00D0B79F36F8),
version (33.3)
]
library AtomLib
{
// Importing stdole2.tlb should be the first statement in the library block. stdole32.tlb is an older
// version and should not really be added
importlib( "stdole2.tlb" );
// Force INeutron, a non-automation compatible, to appear in the type library to enable development tools
// like VB to get information on it
interface INeutron;
// Interfaces inside the library block should have [oleuatomation] or
[dual] attributes (if IDispatch-derived)
// to use the Universal Marshaler
[
uuid(51C3382C-D4D1-11d4-8053-00D0B79F36F8),
object,
oleautomation,
helpstring("Another meaningful description please"),
pointer_default( unique )
]
interface IAtom : IUnknown
{
HRESULT Explode( [out, retval] long *pTeraJoules );
}
// Always define a default interface for VB. If not defined, MIDL
will make the first interface the default one.
coclass Atom
{
[default] interface IAtom;
interface INeutorn;
interface IPositron;
}
};