Creating type libraries using IDL



Type libraries

A type library is an essential part of a component, providing information to the compiler about the classes, interfaces, enumerations, and so on, included in the component.
Type library files have the extension .tlb, although type libraries can also be embedded into other files, such as object libraries (.olb) or dynamic-link libraries (DLLs). Throughout the topics in this section, the term type library may refer to either a .tlb file or to a library contained in another file.

ArcObjects object libraries

Type information for ArcObjects components is contained in a number of object libraries. Each area of ArcObjects functionality is contained in a different object library—for example, the ArcMap user interface classes, interfaces, and enumerations are defined in the esriArcMapUI.olb object library.

Using type libraries

You need to reference a type library to declare variables or implement interfaces using the types defined in the library. The type library is then used when your component is compiled to check the type information to allow early binding of types.
Type libraries also allow type-dependent design-time features, such as Visual Basic (VB) IntelliSense and parameter information, to function correctly.

Creating type libraries

When you create a component, type library information should be created too. The VB compiler automates the process of creating a type library, embedding type library information within your compiled DLL or executable (EXE) file.
If you're developing in VC++, however, you create Interface Definition Language (IDL) files to define the contents of the type library, which are compiled into a separate .tlb file when the project is compiled.

IDL and type libraries

Type libraries are aimed at allowing development to cross programming language boundaries. However, certain incompatibilities exist between the type library information that's created by default and the type library information that can be implemented by different development environments.
Although COM components are accessible from any language, a type library may be required to make the information contained in the component accessible to other developers.
Regardless of the environment you are using, you can ensure your type library is standardized by writing your type library information in IDL and compiling this into a type library.
This could be necessary if you expect your component to be called by or implemented in other environments by other developers within or outside your development team. Multiple type libraries can also be used as an organizational tool to separate interfaces, structures, and enumerations from coclass definitions or to separate public from private information.
This topic covers how you can create a type library by writing IDL, both for a VB and a VC++ project, and the reasons why you might decide to do this. It covers certain issues of writing IDL that can help you ensure that your components can act as a server to a variety of development environments.
The instructions in this topic include the use of the Microsoft Interface Definition Language (MIDL) compiler, and optionally the OLE COM Object Viewer utility (OLE View).

Viewing a type library

Type libraries can be viewed in many different ways, for example, the Microsoft OLE View utility, the Esri Object Browser, and the developer help system.
The Esri libraries are described in VC++, C#, and VB.NET syntax in the ArcObjects component help system.
The Microsoft OLE View utility can be used to view the contents of a type library and unpack the IDL code it contains. In addition to .tlb files, this utility can view the type library information inside a DLL or EXE, an ActiveX control, or an object library file (.olb).
The Esri Object Browser can also be used to view the contents of type libraries in these files. The declarations can be viewed as IDL, as they would appear on an object diagram, or using VB syntax.
If you're a VB developer, you may be most familiar with the VB Object Browser, which shows a VB interpretation of a type library. For more information on what this implies, see the following section on defining interfaces in IDL.

IDL files

IDL is a language that can be used to describe COM interfaces and other data types. Although based on the C language, it can only be used to define data types—it cannot be used to implement interfaces or create classes. For more information on IDL, Essential IDL by Martin Gudgin may be particularly useful for programmers working in VB.
The basic unit of IDL is composed of two parts. First, a section within square brackets contains attributes that define things such as a Globally Unique Identifier (GUID), a version number, helpstring, and help context ID number.
[
  guid(764EDFE5-09A7-11D6-8A8E-00104BB6FCCB),
  version(1.0),   helpcontext(16),
  helpstring("DisplayCommands 1.0 Type Library")
]
This section is directly followed by a named entity to which these attributes apply. The section begins with the entity name, followed by a section within curly brackets, which defines the entity in detail.
library DISPLAYCOMMANDSLib
{
  importlib("stdole32.tlb");    // Import libraries containing
  importlib("stdole2.tlb");     // standard COM API calls.
  importlib("C:\Program Files\ArcGIS\Com\esriFramework.olb");
  [
    object,
    guid(764EDFF1-09A7-11D6-8A8E-00104BB6FCCB),
    helpstring("IZoomIn Interface"),
    pointer_default(unique)
  ]
  interface IZoomIn : IUnknown

Creating a type library for a VC++ component

As a VC++ programmer, you should already be familiar with the process of creating external type libraries by using IDL to define an interface and the MIDL compiler to compile the IDL to a type library file.
If you have experience with Active Template Library (ATL), you may have set MIDL compiler options via the Project Settings dialog box; although because IDL is integrated into the project environment, you may not have been specifically aware of using it.
The MIDL compiler is used by the VC++ environment to create a type library; the MIDL tab of the Project Settings dialog box is used to adjust MIDL compiler settings.
The following sections present a brief review of the steps to turn IDL into a type library for your project.

Creating an IDL file

The basic creation and editing of an IDL file using the ATL COM AppWizard is described in the Development Environments, COM, Visual C++ section of the developer help system.
In summary, there are two steps. First, create a new project using the ATL COM AppWizard. Then use the ATL Object Wizard to add objects to the project, choosing Simple Object as the template. The interface type you choose, dual or custom, depends on the intended usage of the component. At this point, you have a project containing a basic IDL file defining a library.

Adding members to the IDL file

You can easily add interfaces and implement members on your new class by using the context menus on the Visual C++ ClassView. However, you should check the IDL file to make sure it matches what is defined in your C++ code. In particular, check the following:
  • After using the Implement Interface Wizard to implement interfaces on your new class, add these interfaces to the definition of the class in the IDL file.
  • If the interfaces you implemented are defined in another library, for example, the esriFramework object library, import the library using the importlib directive.
  • Ensure that any enumerations are defined in your IDL if they are to be used by clients.

Editing the IDL for client neutrality

If you're creating a component in VC++ that may be used in other environments, for example, VB, you should be aware that not every environment supports all the items you can define in VC++ and IDL.
First, you need to restrict the data types publicly used in your component to those supported in the target environment. Other issues you may want to consider include the following:
  • Interface inheritanceVB cannot implement an interface inherited from another custom interface.
  • Attributes—Various IDL interface, method, and parameter attributes are not supported by VB. This may also affect the way your VC++ method calls are structured.
  • Multiple outbound interfacesVB only supports a single outbound interface to be sinked. You can provide a solution for this problem purely in IDL.
  • Return types—Only error HRESULTS can be converted by VB into errors; positive HRESULT information will be lost in VB.

Compiling the IDL to a type library

When you build your VC++ project, referenced IDL files are compiled to a .tlb file. The compiler switches used can be modified, if necessary, from the MIDL tab of the Project Settings dialog box.

Removing type library information from the DLL

By default, type information is also included in the DLL as a resource. This can be removed. ArcObjects DLLs contain no type information, which is instead contained centrally in the object libraries. You may want to remove type library information from your DLL if you have a particular requirement to reduce the size of the DLL, or to keep type information separate from your implementation code.
You can compile a DLL without type information by ensuring the type library is not included as a resource. From the View menu in Visual Studio, open the Resource Includes dialog box and remove the type library directive. It will look something like the following:
1 TYPELIB "ZoomInSample.tlb"
You can also remove this line directly from the resource (.rc) file if you open it as a text file.
Alternatively, you can leave type information in your DLL, but prevent that information from being entered into the system registry when the DLL is registered. You can do this by changing the RegisterServer call in the DllRegisterServer function of your project to pass a parameter of FALSE.
Type libraries are not always needed at run time, and therefore, are not always present on an install to a user machine. However, if your component is dual interface, the type library is needed at run time to turn IDispatch calls into v-table calls. For this reason, if your component is dual interface, you should not remove the type library information from the component DLL.