May 1998

Using packages in C++Builder 3

by Kent Reisdorph

As we mentioned in the April article "What's New in C++Builder 3," C++Builder 3 includes support for packages, which contain code for C++Builder components. When you get right down to it, a package is just a DLL with the extension BPL. C++Builder uses two types of packages: runtime packages and design packages. Let's take a moment to discuss how components worked in C++Builder 1. Then we'll contrast that with packages and examine how both types of package fit into C++Builder 3.

Components in C++Builder 1

In C++Builder 1, when you installed components to the component palette, C++Builder added the code for the components to the component library DLL, CMPLIB32.CCL. This file loads when C++Builder 1 starts. When you place a component on a form, C++Builder 1 retrieves from CMPLIB32.CLL the code needed to display the component on the form and any property editors for the component. This process allows the component to function at design time. When you build the application, C++Builder 1 extracts the code for the component from the component's object files (OBJ or DCU) and links the code to the application. The application now has everything needed for the component to function at runtime. With that bit of history behind us, let's move on to how C++Builder 3 uses packages. We'll begin with runtime packages.

Runtime packages

Runtime packages contain all the code for a component or group of components. For example, the code for the basic VCL components is contained in a package called VCL30.BPL. When you create an application, you can choose whether to use runtime packages. If you build your application without using runtime packages, it's created essentially the same as it would have been in C++Builder 1. If you use runtime packages, however, none of the code for the components is contained in your application's EXE file. Instead, the code is pulled from the runtime packages at runtime as needed. This is the traditional EXE/DLL relationship.

To enable runtime packages, open the Project Options dialog box and select the Packages page. Select the Use Runtime Packages check box, and C++Builder will build your application so that it uses runtime packages.

Note: A place on the path

Runtime packages called by design packages must be located somewhere on your system's path. The recommended location for these runtime packages is the WINDOWS\SYSTEM directory for Windows 95 or WINDOWS\SYSTEM32 for Windows NT. If you start C++Builder and it can't find a runtime package referenced by a design package, you'll get an error message saying something to the effect of Could not load SOME.BPL. A required package was not found. Do you want to load this package the next time C++Builder starts?

Using runtime packages has advantages and disadvantages. One advantage is that all your applications and DLLs use a common code base (the packages). This commonality eliminates code duplication in every EXE or DLL. As a result, EXEs and DLLs that use runtime packages are smaller. However, this isn't always a good thing, as you'll see next.

The disadvantage to using runtime packages is that you have to ship them with your application. The runtime packages are relatively large, so you must consider the size of your EXE with and without packages to determine whether you're saving anything. For example, let's say your application built without runtime packages is 500KB. The size of the application using runtime packages might be as little as 75KB--but VCL30.BPL itself is 1.4MB, so using runtime packages wouldn't make much sense in that case. However, if you have an application and DLLs that total 10MB, you can probably benefit from runtime packages.

Another disadvantage of using runtime packages is the extra work involved in deploying your application. Let's look at deployment issues in more detail.

Deploying an application using packages

You must know what packages to ship with your application to ensure that you're installing all the right packages and that you're installing them to the correct location on your users' machines. C++Builder comes with several runtime packages. If you choose to use runtime packages, you'll always need to ship VCL30.BPL. If your application is a database application, then you also need VCLDB30.BPL; if you're using any of the Quick Report components, you need QRPT30.BPL; and so on. Besides the packages that come with C++Builder, you may also be using third-party components. If so, you must ship any packages those components require, as well. Use care when you deploy an application that uses runtime packages. The C++Builder license agreement states that you can't alter the VCL packages, and this stipulation helps avoid the problem of mismatched packages (packages having the same name but containing different code). You should use a proven installation program when you deploy applications that use runtime packages. If a package you're installing already exists on a user's system, the installation program will check the version numbers to ensure that the version being installed isn't older than the existing version.

Tip: Which packages do you need?

You can find out which packages your application requires by running the TDUMP utility on the EXE file. The output from TDUMP will show imports from any packages your application requires. Simply scan the output from TDUMP for imports from package files (files with a BPL extension)--you'll have to ship any package files you find.

 
Dynamic RTL

Hand-in-hand with runtime packages is the option to use the dynamic version of the C++ runtime library (RTL). You can enable this option by selecting the Use Dynamic RTL check box on the Linker page of the Project Options dialog box. When this option is enabled, the C++ library code isn't linked to your application, but instead is pulled from CP3240MT.DLL. Like the VCL packages, this DLL is fairly large (1.2MB), so weigh the advantages of using the dynamic version of the RTL carefully. Generally speaking, if you choose to use runtime packages you should also choose to use the dynamic RTL. It doesn't make much sense to use one without the other.

Design packages

The C++Builder IDE uses design packages for components at design time. These packages generally contain the resources required to show the component's icon on the component palette, along with the code and forms for any property editors the component implements. You can use a single package as both a runtime and a design package, but proper implementation dictates that no unnecessary code is contained in the runtime package. For example, there's no reason to include a lot of code and resources (forms) for component editors and property editors in the runtime package, because that code is needed only at design time. If you have a simple component with no property editors, then you can probably get by with a single package that acts as both a design package and a runtime package. A good component library, though, will probably have both design and runtime packages to minimize the size of the runtime package.

You must use a design package to install components on the component palette. Almost all commercial component vendors provide design packages with their component libraries. Sometimes, however, you'll run across a component that doesn't contain a design package. You can still install these components, because C++Builder contains a default design package for any components that don't have their own. Remember, design packages are only for the C++Builder IDE's use--don't ship them with your applications.

Installing design packages

Installing a design package is fairly simple. Just choose Component | Install Packages from the C++Builder main menu to open the Project Options dialog box's Packages page. When you click the Add button to add a package, the Add Design Package dialog opens. Locate the package file (BPL) you wish to add and click the Open button. The package will be listed in the Design Packages list box along with the other installed packages. When you click OK, a message box will open, telling you which new components have been added to the component palette. Click OK again, and the components in the design package will be displayed on the component palette. Notice that there's no rebuilding of the component palette, as there was in C++Builder 1. The C++Builder 3 IDE simply has to load the design packages that are already built (remember, they're really just DLLs) and update the component palette tabs.

You can use most packages created for Delphi 3 in C++Builder, but you'll probably need to rebuild them using the DCC32.EXE that comes with C++Builder. If you have the package source files, you can build the packages from the command line. If you don't have the package source files, then you should contact the component vendor and ask for a package compatible with C++Builder.

You can remove a design package from the component palette in one of two ways. One way is to remove the component completely. To do so, select the component in the Design Packages list box (on the Packages page of the Project Options dialog box) and click the Remove button. The package will be removed from the list and from the component palette. The other way to remove a design package is to leave it in the list of installed packages but clear the check box next to its name. Doing so temporarily removecs the package from the component palette but leaves the component in the list of installed components in case you want to add it again later.

Conclusion

Packages, although a bit confusing at first, are a nice addition to C++Builder. Design packages greatly speed up the process of adding components to the component palette. Runtime packages give you the flexibility to link your application statically (without packages) or dynamically (using runtime packages). Ultimately, you'll create packages for components you create yourself--but that's a discussion for another day.

Kent Reisdorph is a editor of the C++Builder Developer's Journal as well as director of systems and services at TurboPower Software Company, and a member of TeamB, Borland's volunteer online support group. He's the author of Teach Yourself C++Builder in 21 Days and Teach Yourself C++Builder in 14 Days. You can contact Kent at editor@bridgespublishing.com.