Lesson 8 | MIDL: Compiling IDL files |
Objective | Compile MyComInterface.idl. |
Compiling IDL Files
The previous lesson introduced you to IDL. We defined IMyComInterface
and IYourComInterface
using IDL. This lesson builds on that work.
MIDL
Once we have completed our specification using IDL, we compile it using MIDL. MIDL is a command-line tool that comes with Visual C++.
MIDL invokes the Visual C++ command-line compiler (cl). Before you can use MIDL, you need to have the appropriate environment variables set.
The vcvars32.bat file in the DevStudio\Vc\Bin directory sets the appropriate environment variables. The exercise below will guide you through these steps.
What compiling does
Upon successful compilation, several files are produced. For IMyComInterface.idl, these are dlldata.c, IMyComInterface_p.c, IMyComInterface.h, and IMyComInterface_i.c. For now, we don't need dlldata.c and IMyComInterface_p.c. IMyComInterface.h contains both C++ and C definitions of structures to implement
IMyComInterface
and
IYourComInterface
. These definitions use several macros that are defined in various include files, included as part of the Visual C++ environment. Most of the code in IMyComInterface.h is to support C-based COM programming. Because we are using C++, we can ignore this code. Following is a code excerpt from IMyComInterface.h that defines
IMyComInterface
and
IYourComInterface
:
interface DECLSPEC_UUID
("673B0E01-4987-11d2-85C0-08001700C57F")
IMyComInterface : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE Fx1
(unsigned char __RPC_FAR *buf) = 0;
virtual HRESULT STDMETHODCALLTYPE Fx2
(void) = 0;
};
…
interface DECLSPEC_UUID
("24A4A631-4B59-11d2-85C2-08001700C57F")
IYourComInterface : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE Zx1
(LONG ix) = 0;
};
If interested, you can look these macros up, starting in file objbase.h, in the Visual C++ include directory, or by using the Microsoft Platform SDK. File IMyComInterface_i.c defines the value of IID_IMyComInterface
and IID_IYourComInterface
.
Here are the IIDs:
const IID IID_IMyComInterface =
{0x673B0E01, 0x4987,0x11d2,
{0x85,0xC0,0x08,0x00,0x17,
0x00,0xC5,0x7F}};
const IID IID_IYourComInterface =
{0x24A4A631, 0x4B59,0x11d2,
{0x85,0xC2,0x08,0x00,0x17,
0x00,0xC5,0x7F}};
MIDL-generated files include an MIDL-generated interface definition file.
Inside the MIDL-generated files
As discussed above, the MIDL-generated interface definitions use a set of macros defined in a standard include file objbase.h.
Following are the definitions of both interfaces after C++ preprocessing:
struct __declspec(uuid
("673B0E01-4987-11d2-85C0-08001700C57F"))
IMyComInterface : public IUnknown
{
public:
virtual HRESULT __stdcall Fx1
(unsigned char *buf) = 0;
virtual HRESULT __stdcall Fx2( void) = 0;
};
…
struct __declspec(uuid
("24A4A631-4B59-11d2-85C2-08001700C57F"))
IYourComInterface : public IUnknown
{
public:
virtual HRESULT __stdcall Zx1
(LONG ix) = 0;
};
Notice how these definitions are similar to the manually coded version we did in the previous lesson.
Also remember that in C++, with some exceptions, a struct
and a class can be used interchangeably.
The _declspec(uuid(…))
directive is used by Visual C++ to associate the IID with a type of structure.
One difference between this version and the one we did earlier is that these interface member functions are defined as pure virtual.
This means we can not directly instantiate a class/structure of this type. Instead, we derive a class from IMyComInterface
and IYourComInterface
. Do not worry about this for now our objective in this chapter is to study IDL, not to build a COM interface.
midl com - Exercise