Saturday, January 9, 2010

Migrating Existing Delphi Applications to Unicode-enabled Delphi

Over the life of an application it is often necessary or desirable to migrate the application to a newer version of the development environment. By doing so, the application can take advantage of a more modern interface, improvements in performance or memory management, as well as new or improved features.

It comes as no surprise, therefore, that there are many Delphi applications that have been converted, upgraded, and migrated through two or more versions of Delphi.

There is one migration, however, that stands out from the rest. That is the migration of a native code application written in Delphi 2007 or earlier to the latest version. What makes this one so different is that a number of the fundamental data types, types that have been around since the Delphi 1 and Delphi 2 days, have changed. I am talking about String, Char, and PChar, and I am referring to their support for Unicode.

In late 2009, Michael Rozlog, Senior Directory of Delphi Solutions, contacted me to see if I was interested in writing a white paper about migrating Delphi applications to Unicode-enabled Delphi. Ironically, I was in the midst of writing training material about what Unicode support meant for application development. And, I was keenly aware that a Unicode migration white paper, if it was to be effective, needed to rely on much more than just my personal experience. This really was a job for the greater RAD Studio community.

Here was my thinking. Delphi 2009 had been out for almost a year and a half, and Delphi 2010 had shipped three months earlier. As a result, many developers had been through the process of migrating existing applications to the Unicode enabled versions. And, if there was some way of collecting their stories, a clear picture of the migration process would emerge.

The call for stories, code samples, and advice on Unicode migration went out using blogs, tweets, the Embarcadero Developer Network, and some gentle personal prodding of various Delphi experts. And during 6 weeks in October of November I was fortunate enough receive a lot of input. In all, more than 20 contributors provided material, sometimes with a single, valuable code sample, and in other cases, with extensive narratives describing the preparation, process, and techniques used to migrate their applications.

And what a group of contributors this was. A number of them are the innovators behind some of the most popular third-party tools available to Delphi Developers. I also received input from well-known authors, trainers, bloggers, and authorities in the Delphi community. Everyone had something valuable to say, and it all contributed nicely to the paper.

This material is now available in the white paper Delphi Unicode Migration for Mere Mortals: Stories and Advice from the Front Lines. This paper begins with a brief overview of some of the technical aspects of Delphi's Unicode support. It then addresses specific areas of application development that may be affected by the changes to Delphi's default string types.

Throughout the paper you will find direct quotes from the contributors, and in most cases you will also find code samples that reflect the kind of changes that you may have to make to your code as you upgrade existing applications (as well as possible changes to some of the core techniques you are accustom to using). I tried hard to give credit where credit was due, as I strongly feel that a paper of this scope and breadth would be nearly impossible were it not for the generous contributions of the contributors.

To everyone who contributed material, and especially to those brave individuals who agreed to review the paper for technical accuracy, thank you.

If you are preparing to migrate an existing application to Delphi 2010 (or Delphi 2009), or are in the midst of your own migration, you will hopefully find a lot of valuable information in this white paper. I do have one request, however. When you are ready to read the white paper, please download it right before reading. I hope to update this paper sometime in the future with additional material, if it makes sense to do so. In fact, the version of this paper that out there at the time of this writing (January 9th, 2010) includes two corrections that were reported by readers. If you downloaded the PDF prior to January 8th, you have the older version. Get the newer version.

One final note. If you also have stories, advise, or code samples that are not reflected in the current version of the white paper, and would like to have your material considered for a future revision, please do not hesitate to send it to me. I cannot promise that new contributions will actually appear in the paper (there was some nice material that didn't fit into this version), but I would like to consider it.

Send your contributions to cjensen@jensendatasystems.com. Use the subject line "Unicode Migration." I promise to acknowledge every contribution, so if you don't hear from me within a week of sending it, it fell through the cracks. Please resend.

Again, the white paper can be downloaded from Delphi Unicode Migration for Mere Mortals: Stories and Advice from the Front Lines.

Copyright © 2010 Cary Jensen. All Rights Reserved.

8 comments:

  1. You use the StringElementSize function in your examples. I wouldn't use that function because it has a pitfall if you interact with C++Builder code that wasn't migrated correctly and uses AnsiStrings where the Delphi declaration has "String". StringElementSize doesn't do the hidden conversion of the string but almost everything else does, like the Length function or assigning the string to another string.
    That can result in errors if you use StringElementSize on a string that hasn't been magically auto-migrated yet. It would return 1 but the string is later auto-migrated by the $STRINGSLOWDOWN, I mean $STRINGCHECKS compiler switch and has a StringElementSize of 2.

    procedure CBuilderCallsThis(S: string);
    var
    ElementSize: Integer;
    begin
    ElementSize := StringElementSize(S);
    Length(S);
    Assert(ElementSize = StringElementSize(S));
    end;

    procedure Test;
    var
    FromBCB: AnsiString;
    begin
    FromBCB := 'Just a test';
    asm
    mov eax, FromBCB
    call CBuilderCallsThis
    end;
    end;

    ReplyDelete
  2. Hallo Cary!
    Many thanks for your work on this paper! I downloaded the (newer?) version from the link above but shows as date "december 2009" is this the right version?
    Maybe it could be fine if you post the changes in the paper here to make the "errors" more obviuos.
    Thanks again and regards,
    Klaus

    ReplyDelete
  3. This is a write up that I am certainly glad to see and might convince management at my shop to allow us to proceed with one more Delphi 2010 conversion attempt. Our last one ended disastrously as we went a few weeks over our budgeted time in QA trying to run down all the newly created bugs. Eventually the plug was pulled on the project. Management now has us investigating a full conversion to dotNet. While this project is clearly more labor intensive, management views this as modernizing the code and would allow us to hire from a much larger pool of developers. It has been hard to preach the virtues of Delphi with an ever shrinking developer base and large migration hurdles.

    ReplyDelete
  4. Please note ahuser's comment about StringElementSize if you are using C++Builder.

    ReplyDelete
  5. Klaus asked if the document dated December 2009 is the corrected document. It is. If major changes are mode to the document in the future we will identify it with either a version number of a new date. He also asked for a list of the errors that were corrected.

    I will not always be able to accomodate this request, as I expect the changes and additions to future versions of this paper will be too much to document. However, in this case, there where changes to five lines of code. On about page 21, the three FillChar calls were corrected or improved. On about page 29, the two calls to GetModuleFileName were corrected.

    ReplyDelete
  6. Nice Post. thanks for sharing all this info about Delphi

    ReplyDelete
  7. Hi,

    I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading.

    Nice blog. I will keep visiting this blog very often.

    -
    Delphi development

    ReplyDelete
  8. On page 15 'Falling back to AnsiString' second paragraph: "convert String declarations to AnsiString, Chars to WideChars, and PChars to PWideChars". I suppose this should be: "convert String declarations to AnsiString, Chars to AnsiChars, and PChars to PAnsiChars"...

    ReplyDelete