The Interface Definition Language (IDL) has a syntax that closely resembles that of C and C++. An IDL file describes the component and the interfaces that it exposes. An IDL file may contain description of more than one component and each component may have more than one interface. After describing your interfaces and components in IDL, you run them through the MIDL compiler (which is Microsoft’s IDL compiler). The MIDL compiler takes the IDL description of your components and interfaces and generates C++ wrapper classes for our interfaces, type library for our component and C code for proxy-stub DLL.
To be more specific, suppose we create a server called ‘AtlServer’ with ‘Math’ as its coclass name and containing two methods Add( ) and Sub( ). This would create an IDL file AtlServer.IDL. On compilation of this file using MIDL the following files would be generated.
|
|
|
|
|
|
|
|
|
|
Here is a sample IDL file generated using ATL COM. The server name is ‘AtlServer’ and the component name is ‘Math’. Two methods Add( ) and Sub( ) have been added to it.
// AtlServer.idl : IDL source for AtlServer.dll
// This file will be processed by the MIDL tool to
// produce the type library (AtlServer.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(89D5857D-FBE9-11D3-A251-F8FE13E33115),
dual,
helpstring("IMath Interface"),
pointer_default(unique)
]
interface IMath : IDispatch
{
[id(1), helpstring("method Add")] HRESULT Add([in] int n1, [in] int n2, [out,retval] int * n3);
[id(2), helpstring("method Sub")] HRESULT Sub([in] int n1, [in] int n2, [out,retval] int * n3);
};
[
uuid(89D58571-FBE9-11D3-A251-F8FE13E33115),
version(1.0),
helpstring("AtlServer 1.0 Type Library")
]
library ATLSERVERLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(5C8F6A4E-E383-11D3-A24F-8CAC48952A19),
helpstring("Math Class")
]
coclass Math
{
[default] interface IMath;
};
};
Let us analyze the contents of this IDL file part by part.
import:
The file opens with an import statement. The import keyword is used to include definitions from other IDL files. import is similar to the C++ preprocessor command #include, but you can import a file using import as many times as you want without causing redefinition problems. Instead of using two import statements we can rewrite them as
import "oaidl.idl", import "ocidl.idl" ;
Beyond the import statement there are three headers. They are: interface header, coclass header and library header. The contents inside the header are as follows:
object:
We must use object attribute inside interface header, while defining COM interfaces. This is because an IDL file can also be used for defining RPC interfaces. The object attribute helps to distinguish between COM and RPC interfaces.
uuid:
The uuid( ) attribute is used to identify the interface uniquely. The number in parentheses is the interface’s IID. You can see that it’s in some format you’d find in the system registry, minus the braces.
dual:
An Automation object can expose its interface both through IDispatch and through the vtable of a custom interface. This interface is known as a dual interface. In the IDL file it is marked as such by using the dual attribute.
helpstring:
The helpstring attribute is a character string that describes a library, importlib, interface, dispinterface, module, coclass, typedefs, properties, and methods.
pointer_default
This keyword tells the MIDL compiler how to treat pointers if no other attribute is given for a pointer. The Pointer_default keyword has three different options: ref, unique and C pointer. The behaviour of each of these as regards the value that it can take, can it be aliased or not and can it be changed or not is shown in the following table.
| Option | Can be NULL | Can be aliased | Can be changed |
| ref | No | Yes | No |
| unique | Yes | No | Yes |
| C ptr | Yes | Yes | Yes |
On compiling the IDL file using MIDL compiler
it generates the proxy-stub code to marshal function parameters. The properties shown in the table above helps MIDL to optimize the proxy-stub code.
interface:
The interface keyword specifies the name of the interface. The interface definition contains the names of the methods along with the parameters and dispids.
library:
The library statement contains all the information that the MIDL compiler uses to generate a type library. This typically includes the component header, component name and the interface that it is exposing. The interface details are in the interface block discussed earlier.
importlib:
The importlib imports an already existing type library. This directive must precede other descriptions in the library. The imported library, as well as the generated library, must be distributed along with the component so that it is available at run time.
CoClass:
CoClass stands for component class. It contains a list of interfaces supported by the component.
0 comments:
Post a Comment