|Column Tag:||Tools Of The Trade
Cross-platform compatibility, but at a cost
By Edward Ringel
Development, Money, and Reality
As most of us are painfully aware, the Mac OS does not exactly hold a dominant share of the market in personal computers. Therefore, just as a matter of simple economics, anyone who wants to make high-end profits selling software needs to support more than just the Macintosh platform. Furthermore, corporate MIS gurus prefer that users, if they must employ various platforms, should still not only use the same apps but also see similar interfaces - rightly, since this reduces training and support costs.
Its hard, though, for one person to write commercial-quality native code for multiple platforms; and its expensive to have multiple talented programmers for multiple platforms. Consequently, the freelancer with the killer app and the in-house or contract programmer facing a deadline seek the same Holy Grail - write the code once, put it through a bunch of different compilers, come out with applications that work the same way on a variety of platforms, yet preserve the native look and feel of each host platform.
The challenge of making this possible is taken up by XVT Software, Inc., of Boulder, Colorado (www.xvt.com). The resulting product, DSC++ (Development Solution for C++) is a rich environment, but one that may not prove to be the right answer for every developer.
This is an expensive and complex product, and I wanted to evaluate it from within a clearly defined mindset, partly to introduce order, and partly because my comments might influence others purchase or evaluation decisions. Accordingly, I played the role of an experienced Macintosh procedural programmer, ready to migrate to C++ and a framework. I imagined that I had a contract that would ultimately need porting to a second or even third platform, and that therefore I would need a cross-platform tool; I was evaluating DSC++ with intent to purchase.
The depth, breadth, and expense of the product are such that, if purchased, DSC++ would be a core development tool; the expertise, diligence, and policies of XVT Software, Inc., would have a significant impact on your development efforts. Accordingly, this review addresses not only the class library and framework, but the other elements of the package: a C function library that implements a significant portion of the cross-platform compatibility, a universal resource descriptor system, and application construction tools. I also report on my interactions with technical and customer support. I believe that all of this information is critical to being able to make a purchase decision in this rapidly changing area of application development.
Out of the Box
I reviewed DSC++ version 3.22.01 for a 68K Macintosh. The product was installed on a Performa 6200CD, and CodeWarrior 8 was used for builds and perusal of code. The carton weighed fourteen pounds, and contained several books, a few papers, and 7 HD disks. Review of the books is a good place to start, as the printed materials reflect the components of the system:
Tools.h++ Introduction and Reference Manual. Instructions for the use of Tools.h++, a collection of useful foundation classes for data management and manipulation. Used throughout the C++ product.
Guide to XVT Development Solution for C. Guide to the C function underpinnings of the C++ framework and library and the resource language.
Guide to XVT Development Solution for C++. This is the guide to the C++ application framework and the class library.
XVT Portability Toolkit Reference. Comprehensive reference to the function library common to all XVT products.
XVT Power++ Reference. In-depth reference to the class library for DSC++.
XVT Architect Manual. Manual about and tutorial for XVT Architect, the application construction tool for XVT Power++.
XVT Platform-Specific Book for Macintosh and Power Macintosh. Some specifics regarding implementation of XVT products on a Mac OS platform.
XVT Development Solution for C++ Quick Reference; XVT Development Solution for C Quick Reference. Two small books that prototype classes, structs, enums and functions.
The published materials are of the highest quality. They are visually pleasing, physically well manufactured, and very well written. The writers use a consistent, clear, systematic approach to describing functions, classes and functionality. It was very easy to find and learn about material that I wanted to study. In particular, Rogue Waves Tools.h++ manual is among the best pieces of technical writing that I have encountered. The sole exception is the XVT Architect Manual, which was not quite as clear and not at the same depth. Additionally, some of the tutorial code in the XVT Architect Manual did not match exactly that generated by the XVT Architect. However, I could still follow along pretty easily.
Installation of DSC++ was a disappointment, and the first indication that I would be dealing with a product that did not follow the Macintosh Way. The environment comes as a seven-disk Compact Pro self-extracting archive. After performing the extraction, I looked somewhat unhappily through the various folders with their cryptic, UNIX-type designations (pwr, ptk, shell, bin, for instance.) One could argue that retaining this naming convention is a constraint imposed by the cross-platform compatibility requirements, but obviously it defeats one of the nicest features of the Mac OS. I then spent ten minutes sifting through these folders, pulling out several megabytes-worth of Symantec and MPW files unrelated to my CodeWarrior environment. Compact Pro is not an appropriate installer for a complex multi-option installation. (As implied, XVT DSC++ will support CodeWarrior, Symantec, and MPW IDEs. Support for Symantec THINK products was dropped as of March, 1996.)
Content and Structure
My next task was to correlate documentation with files, and to try to develop some mental apprehension of how the pieces fit together (I had to get it). The excellent documentation made this fairly easy.
XVT Portability Toolkit
XVT makes two closely interrelated products, a cross-platform development environment for C, and another for C++. Mac OS, Windows, Windows NT, Sun, and other UNIX platforms (essentially any OS that has a GUI) are supported. XVT has a collection of C functions, the XVT Portability Toolkit, that acts as a uniform interface to the various native GUIs. Thus, to draw a rectangle in the current GrafPort with a 1-by-1 pixel pen, as we might on the Mac with this code:
we write instead:
/* RCT is a rectangle structure that is identical to a Rect */
/* need to set the brush to paint the inside of the rectangle. theWindow is assumed to be previously defined,
and is a long. TL_BRUSH_WHITE is a macro that fills in the fields of a CBRUSH struct, which is a descriptor
of the painting environment. */
/* need to set the pen; TL_PEN_BLACK is a macro that fills in the fields of a CPEN struct */
/* same as the real thing */
/* ditto */
Functions use a uniform naming convention. An XVT call always starts with xvt_. The next word specifies the general category; in this case it is drawing in a window, dwin. The next word specifies the action, such as set or get or draw. Finally, if appropriate, the last word or two indicates the actual object in question, such rect or cpen. The function xvt_dwin_draw_rect, then, is virtually self-explanatory. Of course, before I could even begin to use the product, there would be a whole series of new macros and typedefs to learn. However, this is part of the price of admission to any comprehensive class library and/or framework system. The ability to use the same call with the appropriate result on a Mac, PC, or Sun workstation is obviously the core of this product.
It is important to emphasize the word appropriate: the XVT Toolkit is a layer which interacts with the native toolbox, so that a window on a Mac looks like a Mac window, a scrollbar in Windows looks like a Windows scrollbar, and so on. This permits the cross-platform application to meet the interface expectations of each platforms users. The Portability Toolkit covers a wide variety of operations, though still just a subset of the Macintosh feature set. Features pertaining to the application, clipboard, controls, drawing, windows, dialogs, fonts, texts, images, errors, memory, iostreams, lists, printing, rectangle utilities, and cursors are all supported.
Of course, there may be an efficiency hit. Since all I had are binary libraries I dont know for certain, but I suspect (given the theWindow parameter in xvt_dwin_draw_rect) that the implementation contains code that on a Mac either tests for current GrafPort or does a SetPort() before drawing, adding overhead to every drawing call. Normally, I can SetPort() when I want to, and just do high-speed drawing after my GrafPort is designated. Theres no XVT equivalent.
The dynamic throughout is thus one of well documented, well thought out functions that might well be less efficient than native Toolbox calls. (The XVT Portability Toolkit does not exclude the use of native calls. It is possible to extract WindowPtrs, ControlHandles, and the like, and use them freely. It is possible also to intercept the event loop and process a raw event. However, once you make the code platform-dependent, it is obviously no longer 100% portable.) And, of course, these functions werent what I was used to. Facile use will require an extensive re-education of the programmer. The prospective purchaser must balance the drawbacks of all this against the problems of supporting multiple platforms using multiple native development environments: this is the crux of the purchase decision.
URL and Curl
GUI calls in the absence of some description of the interface make for a cumbersome programming task. The Macintosh concept of resources is appealing, and XVT uses a Universal Resource Language (URL) to describe the GUI components. This resource language is cross-platform portable. In each development scenario, the interface description is translated into the appropriate platform-specific resource descriptor. On the Mac, a URL file is turned into an .r file by curl, an MPW tool which I ran under ToolServer. I then used MPW Rez, still under ToolServer, to create my resource file. There is also a freestanding app, called curl.app, but scripting and the CW environment made curl much easier to use. curl.app was very slow, had a poor interface, and was not user-friendly. (As an example, in order to set access paths for #include files for this program, I needed to type full path names into a specially-named text file.)
The resources described are, again, a subset of the Mac feature set. Window, control, dialog, string, picture, menu, and icon formats form the basic kernel of interface development. URL resources can be created by text coding as with Rez, or by drawing with the XVT Architect application, discussed below. (The companion C product has an application for drawing the interface as well.)
XVT Power++ is the class library and application framework produced by XVT. The class library and framework have similarities to and differences from the big three on the Mac scene (MacApp, TCL, and PowerPlant). The biggest difference, of course, is the absence of reliance on native Mac calls for execution of each method. Instead, a combination of native Macintosh calls (in the binary libraries), C++ methods designed specifically for DSC++, and XVT Portability Toolkit C calls are used for implementation of the functions. Because of this structure, there is often an extra calling layer between C++ and the Macintosh Toolbox.
The general organization of the framework is that of the model-view-controller popularized by Smalltalk. Each application has a single application object which is at the apex of the hierarchy. This object is responsible for opening and closing documents, initializing the application, and the like. The application object has methods for doing saves, changing fonts, etc., which to my recollection is somewhat different from other frameworks on the Mac. Inheritance is generally single (like MacApp), rather than multiple (like PowerPlant). There are a lot of pros and cons to this approach, and while multiple inheritance is elegant and parsimonious, single inheritance is clearer and easier to learn. I think particularly for a cross-platform product, single inheritance is a safer, more appropriate approach.
The application creates a document, which controls the data seen both within a view and in a file. XVTs document diverges from TCL and PowerPlant documents in the ability to incorporate Automatic Data Propagation (ADP) into applications. This feature allows changes in data shared among views to be automatically propagated; when operations in one view change data, the change is reflected in the linked views automatically. Its a bit like having intra-application publish-and-subscribe, which is certainly of considerable value. It is possible to create document-view relationships of significant complexity using ADP. The documentation and explanation of this aspect of XVT Power++ is very well done.
The GUI of the application is handled by view classes and subclasses. Although the nomenclature is different, window, view, pane, scrolling view, and control classes are all supplied. There is a fairly wide variety of graphical elements from which to set up your application. Often the view at the bottom of the hierarchy is a native view, which actually implements the Mac window, scrolling list, text edit field and the like. One very nice feature of the framework is the capability to attach an environment class to a view, window, and/or the application. The environment class automatically defines drawing characteristics for that object, setting the pen, brush, background, font, etc., when that object is the focus of drawing calls. The elements provided permit the production of a typical Macintosh look-and-feel program of early 1990s vintage. There is no support of QuickTime, sound, etc.
XVTs commitment to run on multiple platforms adds the need for a Task Window (the window in which the application runs), which is not necessary on a Mac. This is pretty much transparently handled for you when you use the DSC++ product. Multiple platforms also preclude the tight integration of Apple event handling at the class level. All in all, the framework and class library are very creditable from a structural standpoint, and will permit implementation of a broad range of functionality, but without any of the niceties unique to the Macintosh. As with the Portability Toolkit, the documentation is excellent. This is a good class library comparing very favorably with the big three.
Hooray for Rogue Wave!
In my opinion, the best part of the product is the Tools.h++ Class Library, a set of utility, collection, and storage classes, supplied as headers and object files, from Rogue Wave. It is possible to implement a wide variety of memory and file structures very simply just by deriving subclasses from those supplied with the library. Lists, unordered collections, hash tables, b-trees, strings, and many, many other very useful objects, coupled with the framework, make it possible to create and maintain complex data structures with DSC++. Since the data structures of Tools.h++ are the underpinning of the XVT Power++ data structures themselves, integration is easy and reasonably intuitive. There exists in the Rogue Wave library the ability to create data structures which are platform-independent as well, implying cross-platform file compatibility. The Tools.h++ manual is wonderful and an education in intelligent C++ programming. These high-quality utility and storage classes really make this product stand apart from the big three, and are among the most compelling arguments for purchasing this product, cross-platform issues notwithstanding.
The strength of the data management capability of the framework reflects the workhorse nature of this product. It is very much a system for facilitating access to data and for managing the GUI to that data. This is almost certainly due to the fundamental data orientation of many of the other platforms supported by XVT, for which the GUI is ultimately secondary. I suspect that many of the corporate clients demanding cross-platform applications care far more about efficient data manipulation than the latest GUI features, Apple events, or QuickTime, and that the GUI offered by XVT is more than adequate for very good corporate in-house applications.
Figure 1. Blueprint window for XVT Architect. The application, documents, and windows are represented as icons, which are instantiated by choosing the document or windows tools. These objects are linked using the linking tool.
XVT Architect is the application construction program supplied by XVT, permitting the programmer to draw the application. XVT Architect has three different modules, referred to by XVT as interfaces. Initially, in Blueprint interface, the programmer defines the relationships among the different documents and windows, and thus defines the applications runtime object hierarchy. This is done by instantiating an icon of either a document or a window, and then connecting the objects with a linking tool.
Drafting interface permits the programmer to draw views, windows, and menus and the various control and text entities. The various classes available in XVT Power++ are available as drawing elements in XVT Architect.
Figure 2. Drafting window for XVT Architect. The window under construction is to the left. Palettes of views, text types, and controls have been torn off so that they may be easily used.
Strata interface permits the programmer to set the characteristics of the various objects and classes. For example, if you wish to set the editable text view youve just created to use the parent windows scroll bars, this would be done in the Strata interface. It is possible to set all of the characteristics of all of the ancestor classes of the object in development. The characteristics are grouped by class derivation. In this respect, the Strata paradigm is particularly easy to use, as you can mentally break down the task into its component parts much more easily.
XVT Architect is slow and requires a 6MB partition to run reasonably. The factory-set partition on XVT Architect was not set correctly. Many of the design elements (such as the tear-off menus) are foreign-appearing. There was less than adequate attention to design: captions intruded into editable areas, and so on. I unintentionally created a low memory condition and XVT Architect handled this poorly; it did put up an alert that I had a memory problem, but then it corrupted its heap and ultimately crashed my computer before I could do anything to recover from my error. In one operation, clicking a button brought up a modal dialog that was positioned so that it was partially off the screen; given that I have a 15-inch screen, this is inappropriate. As a member of the over-forty crowd, and getting closer to bifocals than I want to admit, I was grateful for 12-point Chicago as the font of choice; however, by current standards of Mac design and aesthetics, it was unappealing. There were a number of areas where the ability to resize windows was ill-considered, and some of the visual clues that Mac users are used to were missing.
Figure 3. Strata window for XVT Architect. The class hierarchy for a scrollable text view is shown. The behaviors of the object can be set with this tool. All parent class characteristics can be set in each classs window. Along the bottom of the window,
the hierarchy is represented iconically.
Clicking on the icon brings up the relevant view.
When design is complete, XVT Architect will generate two sets of source code files. Much like Symantecs Visual Architect, XVT Architect creates Factory files, which create the objects and interface and are not meant to be modified by the programmer. These files are regenerated as the interface is changed. The second set of files is used by the programmer to implement the functionality of the application. These files are commented to show what code should be added or changed, and where. XVT Architect also creates a URL file and a script to automate the build of the project. To use this script under CodeWarrior, I had to add ToolServer to my environment (which I normally do not use), but once I got the configuration right, the build went forward flawlessly.
I have always had a love/hate relationship with interface builders. Whenever I see the line //your code here I cringe, because it requires that I enter another programmers head and follow his or her way of doing things. Putting that bias aside, though, the concept behind XVT Architect is not bad at all, and XVT Architect uses the successful strategy of double file-generation to minimize enforced coding style. Certain aspects, such as the Strata interface, are particularly well thought out. Ultimately, Architect needs a lot more attention to detail and a big speed boost before I would be happy using it as a core development tool.
Figure 4. Oops! This XVT Architect modal dialog was placed partially off the 15-inch screen.
I used example/tutorial code supplied by XVT as my test of compilation. Some operating systems do not permit file names longer than 8 characters. To achieve cross-platform compatibility, XVT #defines a descriptive macro for the name of each .h file, and the programmer #includes the macro rather than the true name of the file. This is great for Windows, but obviously unnecessary on the Mac. It also defeated CodeWarriors mechanism for creating a pop-up menu of .h files, and I could not use the normal navigation techniques. I also could not get CW8s browser to parse projects. It was quite difficult to create a precompiled header for the projects, and I eventually needed to call tech support for help; even then I needed to modify factory-supplied .h files to achieve compilation of the header. The large number of compiler switches necessary for the various environments ultimately left some undefined compiler variables in the .h files which needed to be manually set. As pointed out by XVT tech support, there is apparently a bug in CodeWarrior 8 which does not permit proper handling of static variables in precompiled headers; XVT uses statics in its headers. I did not try to resolve this problem.
I worked through a couple of tutorial sessions using XVT Architect. The AppleScript script-directed build had set up my access paths correctly, and all files were available; I did not need to intervene manually to initiate compilation. The XVT Architect-generated projects compiled and ran flawlessly. In the absence of header precompilation, a simple scrollable, editable text window application required compilation of over a quarter of a million lines of code. This same 68K application was over 600K in size and required a 2MB partition to launch without crashing.
I also compiled several of the example projects. These had been created without XVT Architect. I built these by hand, using curl.app to translate the URL file into an .r file, then using CWs Rez plug-in compiler to add the resources to the project, and finally compiling the C++ code as well. These projects all compiled without error, but at execution all failed initialization and aborted. They did not crash the computer. At this point, I was sufficiently frustrated that I did not try to resolve this problem either.
A number of the default behaviors of the objects are not appropriate for a Mac. For example, the demo applications appeared to have difficulty with mapping keystrokes properly, and again there were problems with placement of the windows on the screen.
Figure 5. DSC++ handles keystrokes improperly. The compiled, fully functional tutorial contains a notepad window. The figure shows the results of typing Now is the time for all good men to come to the aid of their country into that notepad window.
The product comes with a number of Mac-specific extensions. As I stated previously, it is possible to implement Apple events, but this is not an integral part of the product, and has nothing approaching the support of PowerPlant, much less TCL. In brief, the XVT main event loop calls AEProcessAppleEvent(); all that needs to be done is to install the handlers. I am not an expert Apple event programmer, but it would seem that the structure needed to implement the events makes it hard to use the object model to create elaborate scripting and interapplication communication, but fairly straightforward to do some basic AE work. It is possible to retrieve handles to Mac data structures such as lists, editable text, and the like. It is possible to work with Mac resources directly, and, for example, directions are given on how to use Finder icons. There is a short manual devoted exclusively to Mac issues which is as well written and descriptive as the other written materials. The Mac-specific extensions are not all-inclusive, and the majority of the manual deals with resource issues.
When I first received this product from MacTech Magazines offices, the code would not work out of the box: the CW7 libraries would not work under CW8 because, as many of you recall, this was a recompilation required update in the Metrowerks environment. I attempted to get customer support via email, giving the serial number on the master disk. I was courteously (but firmly) intercepted by a sales manager who had no record of a sale to me, and basically wanted to know what I was doing with this serial number. I explained who I was and how I acquired this copy, and so all subsequent contacts with the company occurred with their full knowledge of my status as a reviewer. Nevertheless, despite that knowledge and despite intervention from both the sales manager and XVTs public relations firm [not to mention some well-chosen words from a certain magazine editor - man], it took nearly two weeks before my status was resolved and I was given a password to their secure FTP site so I could download over 12MB of patch. Obviously, as someone active in the software industry, I am very respectful of licensing issues; however, I would have hoped that, once I was identified as a legitimate user with a special problem, access issues could have been resolved more speedily.
There was, it turned out, no update or patch; the download was simply the same, complete product as on the distribution disk, updated for use with CW8 and with a few bugs taken out. It used the same Compact Pro archive. This archive was dated March 21, 1996, which was quite disturbing, as it implied (given Metrowerks release cycle) that it had taken XVT in excess of two months to recompile their CodeWarrior libraries and to make them available for download (I had been told by the sales manager that the company was just completing this update when I first got in touch with them about this issue). While two months might not seem a long time, the Metrowerks (and Symantec) release cycle is four months, so companies supporting those development environments must occasionally expect to have to do some quick work to keep their customers happy; this, for good or ill, is part of doing business on the Mac platform.
Contact with tech support itself was mostly by email, and they were interested, helpful, and prompt. I dealt repeatedly with a single member of the tech support staff, and he (Patrick Gorman, thank you again) did appear to know both the Macintosh and the XVT product well. As an example, I asked for some help with implementing Apple events, and I was given good instructions.
A number of companies are development partners with XVT and offer extension products with compatible APIs, ranging from word-processing engines to connectivity/database front-end extensions. Not all of these products are Mac-compatible. The guide clearly states which products are compatible with which platform. I have been told by the sales staff at XVT that a release of XVT DSC++ that is due out shortly will include a number of Power Objects, which are complex interface objects that simplify GUI tasks. A Table object is included as part of the tutorial.
All executable code is in precompiled libraries, with the exception of XVT Power++, which comes also as source code. The price is $2325 per platform per developer; 68K and PPC Mac are considered two different platforms. A complete source code version is over $29,000. The primary clients appear to be large corporations doing in-house programming, or programmers contracting with a large corporation to do the same. The sums involved are substantial, and the relationship between client and vendor potentially a long one. XVT has a program whereby a prospective client gets special technical support with calls, emails, etc., while the product is being evaluated. I was told by the sales staff that a prospective purchaser can attend XVTs classroom program on using DSC++ in Colorado without cost (you supply airfare, room, board; they supply the training), to get a good feeling for how the product works and to see if it really is for your company. XVT has a clear sense that their best sales tool is making sure, as I put it earlier, that you get it. I think they are right; a happy customer is a return customer, and probably makes tech support simpler.
Did I Get It?
I think so. XVT Software has produced a product that implements a C code interface to a common subset of the GUI features of a variety of platforms. It has produced a resource language that supports this GUI mechanism. It has created a quality class library and application framework that uses this interface to create platform-independent applications using C++. XVT Architect is a visual tool for creating class relationships and drawing the GUI. The C++ product is very much data-oriented, supporting out of the box a much wider array of data types than native Mac frameworks, and has a mechanism that simplifies sharing data among multiple views. There is a lack of finish in the tools, and the code itself is not as easy to use as Id like. I was quite disappointed by the behavior of the example projects. The problems with the tools, the example code, the slow update of the CW libraries, and the difficulty with the FTP account left me with a lingering overall caution about the product despite underlying good documentation and thoughtful overall product design. The applications produced are large and slow, and, though the matter is hard to quantify (and XVT Software will probably disagree), there seems to be a general underlying incomprehension of or indifference to the Macintosh Way - the sense of style, the attention to detail, the ease of use (even for programming tools) that we take for granted. Finally, this product, despite its positives and the good intentions of XVT Software, is constrained to a common denominator defined by less sophisticated platforms.
I would not use this program to write my killer app and then port to Windows. However, efficiency, ease of use and productivity are ultimately in the eye of the beholder. A large contracting concern or a large corporation with an in-house programming department might well choose a product such as XVT, declare it the standard, and find that it meets the needs of the company and/or the contract more than adequately. Indeed, the efficiency of programming and meeting corporate MIS needs could more than make up for the speed bumps and lack of polish that would be encountered when a uniform solution was demanded of many individuals using multiple platforms. Thus, I could see XVT DSC++ as a potentially useful tool for a multiple-platform in-house programming staff. On the other hand, certain applications might suffer from the speed issues and the lack of ability to customize and take full advantage of the Mac interface. Ultimately, my recommendation is to take full advantage of XVTs evaluation program, and make your own decision.