Basic COM  «Prev  Next»
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

Click the Exercise link below to configure environment variables for MIDL and to compile IMyComInterface.idl.
midl com - Exercise