|
|
t e m p o r a l |
d o o r w a y |
|||||||||||||||||||
Migrating To C++ Builder 3 |
|||||||||||||||||||||
IntroductionMigrating to C++ Builder 3 requires a number of changes in your thinking, especially if you are a component developer. This is not the same as C++ Builder 1, not by a long shot. Run-Time PackagesThe new component model allows - no, requires - you to develop each component in a separate package[footnote 1]. A package is essentially a .dll, but it produces a .bpl file. The .bpl file must be on the search path as defined by the PATH environment variable. This document does not presume you use run-time packages, but if you do, you must have the directory used for your component package in the PATH, the appropriate option needs to be checked in the project options, and you must remember to deploy the .bpl file to your users. You can also statically link the package to your application, but the .bpl will still be needed for design time interaction. Getting Ready
Preparing For MigrationThe hardest thing to do in any new development system is to establish a good directory structure and naming conventions. Usually you are required to do this before you understand the implications of your choice, and by the time you discover problems with your decision, it is so difficult to shift that an improved structure is never attained. All I can do here is tell you about the choices I made and why. Hopefully this will help you think clearly about your own alternatives. My previous structure was not too bad. I had a directory for components, a directory for non-component classes used by components and projects, and a directory hierarchy for projects, based on the inheritance hierarchy for those projects. Each file name was kept identical to the class name implemented in the file. There were a few cases where that rule was not followed, due to some bug in Borland make which forced recompile of certain files even when that was not necessary - apparently based on file name. At any rate, I decided to alter the file names to strict compliance with class name as they were migrated. I also decided to maintain the directory structure. But I quickly found I would need to change my naming convention. Packages alter one's thinking on components. Where a component used to consist of a .h and .cpp with .obj, it now consists of a .h, .cpp, .bpk (package make), a package dll .cpp, .bpi (import library), .bpl (package dll), and, annoyingly, a very very large .tds (about 7Mb per package on my system). Where before you had only to worry about the name of the .cpp, you now also have to worry about the name of the project, as with any application. To keep things simple and readable in the project manager, which now is required for component development, I decided to name the project <classname>Package (which name affects the package.bpk and .cpp, etc), and the component <classname>Component. Is This A Pain, Or What?The trade-off with this change in component development is basically this:
If you build or frequently modify components, then the fast turnaround of component changes is an advantage, and, presumably, the automation of component creation by the IDE is sufficient to overcome the additional complexity. On the other hand, if you seldom create your own components, you may find the additional complexity daunting. Hang in there - it isn't that hard, and the migration of your own components from C++ Builder 1 to C++ Builder 3 will be enough to get you used to the problems. Starting The Migration Of ComponentsMigrate independent components first - the components which are used or derived by other components. This simplifies your task, especially while you are learning the new style of development. Make copies of your C++ Builder 1 directories and alter the structure to reflect any changes you've decided to make. Work with the copies. For each component, follow these steps:
Some Signs Of Error
TestingIt's not a bad idea to test the newly installed component right away. Why wait? Have a Test directory under the Component directory, and create a test project for each component. Grouping Your Components To Make Them Acceptable To The IDEI have a library of 50 or so components. Some of them inherit from others. Some of them use others as part of an aggregate. One is based on an ActiveX control. As the migration of these components progressed, it became clear that there was sonething wrong with my initial strategy to convert each component to a separate package. Here's what I tried and what happened... Strategy 1:Follow the book. Add "PACKAGE" to class and Register() declarations. Add "#pragma package (smart_init)" to every component .cpp. Create a package for every component using the Install Component dialog, and add the component; use a good description of the component for improved documentation. Combine the packages into a project group for documentation and access purposes. Result of Strategy 1:Random Invalid Page Faults in the run time library CP3240MT.dll when a component is being installed. Some components install correctly. Deinstalling all of my component packages and then reinstalling the problem package goes fine - the abort then shows up on the installation of some other package. This suggests that the problem is not in the specific package, but is probably a C++ Builder bug or an operating system issue. Strategy 2:Use Strategy 1, but change the description of the components to be shorter - in fact, to the name of the class. This makes it easier to keep track of which components have been loaded and which haven't, to make absolutely sure there is no problem that can be isolated to a specific component. Also, some systems have problems with long strings in certain contexts - perhaps this is one. Result of Strategy 2:Now I get an error message on the component installation which states that one component package includes something already in another installed component package and that therefore I won't be allowed to install it (very suggestive that the previous aborts were caused by a reaction to the length of the package description). Inspection of the "requires" for the package shows it contains a reference to the specified .bpi (which it needs, but the message says take it out). I remove that reference. I build the package. The build tells me I need the reference I already removed from the requires. I tell it not to add the reference. I try to install the package. The IDE then claims the package still contains the reference that was removed. I check the package. The reference is definitely not there. I delete the compiler and linker output files and build again. The IDE still claims that the package to be installed contains the reference. But the only thing in the package is the include file for the absolutely necessary headers. Strategy 3:Make a single package containing all of the component units. Build the package and install it. Accept the things it wants to add to "Requires". Result of Strategy 3:It works. The package can be installed, the components show up on the palette. Conclusion (?)There is some sort of bug in the handling of a) large number of separate component packages (i.e. > 20) and b) long descriptions for component packages. There is also a bug in the way the IDE is dealing with intercomponent / interpackage references, which includes a) not resolving duplicate .bpi imports in some contexts (it is not clear to me what those contexts are, since clearly all component packages probably reference VCL packages, and yet there is no problem with that duplication) and b) believing those .bpi imports are present when they have been removed (possibly based on the presence of an include in the component source header file). None of these restrictions is documented. The documentation seems to clearly indicate that each package should contain a component and that any other organization is the exception rather than the rule (see the help file on "Components,Converting components from CBuilder 1.0"). But there is an upside. Strategy 3 compiles and makes much faster than any of the others when you need to remake all of your components. A 20 member program group takes over a half hour to rebuild or remake, even when the average compile is around 20 secs. The strategy 3 package takes only a fraction of that time. Application MigrationThis isn't terribly difficult if you correctly migrated your components. Backup your application and its project. Then open the project in CBuilder 3. You will be notified that it is being converted. C++ Builder will not change the name of the project from .mak to .bpr when you save it, nor will it allow you to save the project as a .bpr extension file. So once you have opened the project, save it, and then exit C++ Builder, and rename the project to have the .bpr extension. Make sure all of your paths and run time component search paths and package names are correct, otherwise you may get unusual errors when loading, compiling, or linking your application project. What Can Go Wrong
Footnotes1. Or so it seemed at the time. New information suggests this is not the case. |
|||||||||||||||||||||
|
Copyright © 2004 by Mark
Cashman (unless otherwise indicated), All Rights Reserved
|