Monday, January 19, 2004

Commenting changes. 


Sorry for being a little flakey here, but it turns out that I can use php pages on http://homepages.borland.com. So I've downloaded and implemented comments locally instead of using the HaloScan. This way I'm less at the whim of a separate hosting company and closer to it all being integrated into the Borland community site.

Thursday, January 15, 2004

More IDE secrets - UTF8 and the Editor 


In C#Builder and Delphi8, the code editor operates internally on UTF8 characters only. This requires a "filtering" mechanism to translate from/to various other text file formats when the file is loaded or saved. These are the "filters" you can select by right-clicking in the editor and selecting the encoding from the menu. By default, the editor will store the file as locale-specific ANSI encoding which can lead to a potential loss of character data if a file from another locale using a different code-page were loaded and saved. You can change the default encoding of the files to always be UTF8 by setting the following key:

C#Builder: HKCU\Software\Borland\BDS\1.0\Editor
Delphi 8: HKCU\Software\Borland\BDS\2.0\Editor

DefaultFileFilter="Borland.FileFilter.UTF8ToUTF8"

Using UTF8 encoding when operating on a file in memory instead of straight UCS-2 (Unicode) was done for efficiency, not only in implementation time, but also in terms of memory usage. The editor kernel already knew how to manage middle- and far-eastern multibyte codepages, so extending the kernel to simply treat UTF8 as simply another multi-byte encoding was a relatively trivial excercise. Also, since the vast majority of source files contain only characters from the 0-127 ASCII range, each character will remain a single byte. Only embedded strings and comments would typically have extended (>128) characters. Also, UTF8 conversion is a very fast bit-level transform without the need for look-up tables. This allows the editor painting code to do a simple quick transform into UCS-2 and then use the Unicode APIs for painting the text. This way, a file created from one locale will render correctly when opened and edited in another locale since the UTF8/Unicode character space includes encodings for all languages.

Wednesday, January 14, 2004

Commenting.. 


I've gone ahead and added commenting to this blog. It is currently hosted by HaloScan, which is a free comment hosting site. Eventually, this whole sha-bang, will move to using a Borland provided blogging and commenting system. For now I'll stick with what is already out there and available.

Sunday, January 11, 2004

Where's Waldo... er... Allen? 


It's been close to a month since my last blog entry and a *lot* of stuff has happened since then, both personal and corporate. On the corporate front, Delphi 8 for .NET was released to manufacturing on Dec 19, 2003. This is great news because it meant we were able to take advantage of the two-week corporate shut-down.

On the personal front, I lost a very dear person in my life. On December 30th, my mother succumbed to lung cancer. This was quite a shock to my family as she has never smoked a day in her life. However, I am truly thankful that I was able to be with her for her last few days and was by her side the moment she passed along with my wife, sister and brother-in-law. She will be sorely missed. So, until our spirits meet again, bye Mom...

The next few weeks are going to be interesting as we begin execution and planning for the next product releases. I will try and keep things going here, but there will certainly be many distractions as the meeting counts increase and while we slog through the details of planning product cycles.

Tuesday, December 16, 2003

IDE Spelunking... 


Ever wonder what the line break style is for each line in a text file? Well, there is a way to find out without opening the file in a hex-editor. If you have C#Builder, and will be in the upcoming Delphi 8 for Microsoft .NET, there is a hidden setting that will tell the editor to display special unique characters at the end of each line that will represent the style of line-break.

"HKCU\Software\Borland\BDS\x.x\Editor\Source Options\xxx\Show line breaks" = "True"

Where:
  • x.x = 1.0 for C#Builder and 2.0 for Delphi 8

  • xxx = Sub key for specific file types



  • !DANGER! WILL ROBINSON... 


    In previous versions of Delphi, when a user built a package, the IDE provided significant assistance in making sure the package was being built correctly by limiting what units got implicitly linked into the package. In Delphi 8 for the Microsoft .NET Framework, much of this assistance isn't being done due to the overwhelming complexity of the problem now that we've moved into the managed space. Currently, when you build a package/assembly, this is ones using the "package" keyword, not using library, which I'll comment on later, the compiler will display warnings when any unit was implicitly linked into the package. Please treat these as ERRORS. In a future release of the D4Net compiler, these warnings will change to errors.

    What does this mean?

    You must make sure that your "requires" clause refers to the proper Delphi assemblies and your "contains" clause explicitly lists all the units to be included in the package/assembly. What has been happening, is that folks have been blithely ignoring those errors, then proceeding to wonder why their component behaves strangely when they load it into the IDE designer. If you see any "implicitly linked unit" warnings, you need to eliminate them. For instance, if you see a warning that states Borland.Vcl.Classes was implicitly linked into your package, you forgot to add Borland.VclRtl to the "requires" clause. The same if you see Borland.Vcl.Controls implicit link warning, only you forgot Borland.Vcl.

    Yes there are cases where this is legitimate, like you want to build your own specific run-time assembly with a mix of VCL units and your custom units. However, the rules regarding the use of an assembly/package such as this haven't changed... you can't build one that links into itself *any* Borland supplied .dcu/.dcuils. or to any non-Borland supplied package/assembly that does.

    What's the big deal, its the same code, right?

    Yes, the actual machine/IL instructions are the same, however that isn't the only thing in the assembly. There is all that metadata (this is also true for Delphi/win32) that describes certain types, such as classes, records, enums, etc... CLR is a little better at this because it will never mistake one type for another because it always internally deals with types as full assembly qualified names.
    Suppose you have two assemblies, A1.dll and A2.dll. You linked into both of these assemblies, the MyComp class. To the CLR, the MyComp class name in A1.dll is actually, "MyNamespace.MyComp, A1" which, to the CLR, is a totally different type than "MyNamespace.MyComp, A2." They are not interchangeable.

    But C# lets me do this.

    Oh sure it does.. you keep telling yourself that. Yes, C# does allow you to create two assemblies that contain the same class, however it also warns you and will select only one of the MyComp types to use in the calling assembly/.exe. Even Delphi has always allowed you to do this. The problem comes in when you want to load those assemblies/packages into the same process/AppDomain. Consider this scenario, you have assemblies B1.dll and B2.dll, each of which uses A1.dll and A2.dll respectively. B1 and B2 contain all unique types, so all is well... not! What if B1 has a class that descends from "MyNamespace.MyComp, A1" and B2 does the same with A2? Now you have a third assembly/.exe, C, that uses A1, B1 and B2 only. It knows nothing of A2. C constructs an instance of the MyComp descendent from B2. If you did an "as" cast or and "is" test, it will *not* report that it is a MyComp descendent.

    If you did the above scenario with Delphi, when it came time to link with A1, B1, and B2, you would also implicitly link with A2. When the compiler goes to link things together, it will discover that you have the same unit in A1 and A2 then fail to link. If the A1 and A2 assemblies were not Delphi written, then the compiler will still detect that it is importing two types that appear to be the same name and it will issue a warning and select one with which to link, just like C#.

    So the bottom line is that a type can exist in one and only one place within a process/AppDomain. In fact this has always been the rule for Delphi/Win32 as well. So, again, I find myself saying that the rules have not changed.


    Friday, November 21, 2003

    The rules have not changed... 


    Let's hear it for Garbage Collection! Hip-Hip-Ho.... whoa there Nellie!! When it comes to VCL for .NET and Garbage Collection, the more things change, the more they stay the same..

    The level of source-code compatibility between the traditional VCL/Win32 and VCL/.NET is nothing short of amazing. If you witnessed the Product Address at this year's Borland Developer Conference, you would have seen a demo where the original FishFact database demo was opened in Octane (Delphi 8 for .NET), compiled and ran with 0 (zero), count them, 0(zero) code changes. Not even the uses lists needed to change (remember WinTypes, and WinProcs? ;-).

    OK, so they're compatible... What does this have to do with Garbage Collection? Well... there are some myths around GC that may get you in some serious trouble. Yes, it is true that in a GC environment, you generally don't have to worry about freeing memory. However there are a lot more types of resources than simply memory. Things like file handles, GDI handles, etc... It is easy to understand that these items are out of the reach of the GC, so you have to continue to guard your code with try..finally blocks to open/close, allocate/release, etc.. What is more subtle, though, are those "resources" that don't quite "fit" the definition of an "object."

    So what other kinds of "resources" out there have to be managed in a similar fashion to those more traditional notion of a resource? I use the term "resource" loosely here in order to simply highlight the correlation to what one normally thinks of as a "resource." Suppose you have a class of objects that have specific knowledge of the container in which they live. When you create an instance of one of these object classes, they are given the container and proceed to toss themselves into that container. You now have this "bag" of objects by referencing the container. You can pick each item from the bag perform some operation on them. One suich operation that is common is to "destroy" the item. Well, since this item knows about its container, it plays nice and removes itself from the container before it self-destructs.

    In the GC world, a common mistake is to simply think of "destroying" an object is simply freeing its memory. So I don't have to do that in the GC world because that will be handled for me, right? Sure it will.. eventually. But it will not automatically take care of one important resource, it's container's reference. That reference needs to be cleaned up. It is not a "resource" onto which the item itself holds, but is a resource nonetheless. When you look at the declaration of the object, you won't find a reference to this resource... oh wait yes you do... It is the reference to the container itself. It is through this reference that the "resource" lives.

    So if you don't "destroy" an object, how do you make it release its references? In .NET, there is a simple pattern that is followed. An object that needs to do immediate resource cleanup, should implement the IDisposable interface. It has one method called procedure Dispose; (or for you that prefer a more "curly" world void Dispose();). Now when you want to "destroy" an item in the container, you cast the item to IDisposable and call the Dispose method. In the Dispose method it just performs the nessesary steps to remove itself from the container.

    Sure, you could manually remove the item from the container yourself and forgo the IDisposable riggamarole, but what if you hand the item off to someone that has no specific knowledge of the particular container instance in which the object is currently living? This is why the IDisposable pattern is important.

    So let's bring all this around now to Delphi 8 for .NET and its view of the world. All this IDisposable stuff seems tedious and would require some massive changes to my code to play nicely in .NET. This is where Delphi has realized some of the benefit of arriving a little later to the party. Delphi introduces an interesting language construct called "class helpers." There could be a whole tome written about the subject of "class helpers", but suffice it to say, they have given the Delphi programmer a familiar world in which to work. All that code you have written in which you dutifully have implemented your destructors to properly clean up after yourself, release resources, and generally keep your house in order can now continue to live on..and serve a real purpose beyond simply releasing memory. Releasing memory is no longer the responsibility of the lowly Destroy destructor. It now is a cue to the Delphi compiler that you want it to implement the IDisposable pattern for you. Your object now implicitly implements IDisposable and the Dispose method maps to your Destroy destructor. It even takes care of guarding your destructor from being called more than once by implementing the pattern of setting a compiler generated instance variable to true the first time through the Destroy destructor and exits immediately on all subsequent calls. To the world outside Delphi, your objects simply appear to implement the IDisposable pattern. The really cool thing though, is that all objects that come in from outside Delphi (remember all objects in .NET descend from System.Object, which is not Delphi's System.TObject. In the CLR world, it is the other way around. Borland.Delphi.System.TObject = System.Object) "appear" to have a non-virtual method called Free (thank you class helpers). If you are a seasoned Delphi developer, you know that in order to maintain proper "exception safety" you never call the Destroy destructor directly. This is because the Free method would check to make sure Self (or this) is non-nil before calling Destroy. In .NET it continues to do this as well, but now it checks if Self implements IDisposable and then calls Dispose if it does. This is why you can call MyHashTable.Free. Through the magic of class helpers, the Free method appears to be a method of HashTable.

    So now all your nicely done try...finally code continues to serve a purpose, in fact is remains critical to the proper operation of VCL code. For instance, a TComponent derivitive takes an Owner parameter in its constructor. It then proceeds to add itself to the Owner's list of Owned Components. So, when you call Free on the component, the expectation is that that component is removed from the Owner's list immediately. These semantics are now preserved.

    Garbage collection certainly takes away certain programming chores, but it is not a panacea. The more you understand the environment in into which you are moving, the better you'll be able to migrate your existing code. So the upsot of all this is that you don't have to change nearly as much code as I'm sure you originally thought nor should you.

    Thursday, November 13, 2003

    Up periscope... 


    Just a quick note here... For those two or three folks that seem to be gluttons for punishment and actually read this jumbled mess of random thoughts... I hope to be back in the blog saddle within the next few weeks. I need to make good on the promise that I'd present some of the material I had planned on preseting in my "IDE Spelunking" BorCon talk that was canceled.

    Monday, November 10, 2003

    Aftermath 


    Now that the 2003 BorCon is behind us, we are now "kickin' it up a notch" for that final drive to release. This is mainly why the blogs have been coming less frequently... that whole "work" thing keeps cutting into my blog time ;-)... Also we're at that stage where the days are sort of blending together...

    It seems the rainy season here in Santa Cruz, County, CA has started in earnest. While it is sunny today, the past week was filled with dark overcast foggy skies. That certainly makes it easier to keep ones head down and concentrate on completing the release.

    Wednesday, November 05, 2003

    BorCon talk 


    I just finished my one talk I was still giving at BorCon and am now back in the office... It was a small crowd, but it always is since Open ToolsAPI stuff isn't a huge draw. I got to present some interesting things, like we plan on publishing a Delphi/C#Builder integration package to registered users and partners to allow them to move thier existing Delphi and/or C#Builder IDE plug-ins over from Delphi 7.

    Stay tuned.

    Friday, October 31, 2003

    Avalon: Yes, the Picture's Changing 


    Avalon: Yes, the Picture's Changing

    Here's a response that I posted to the above article:

    I can see everyone rolling their eyes at the loony that is about to make this statement.

    The movement of the declarative "InitializeComponents()" code to another more suitable "language" is nothing new, nor earth-shattering. Now comes the controversial part. Take a look at Borland Delphi... "Oh, I've heard of that" No, it is *not* just that "database" tool. It is a full featured, powerful object-oriented, component-based, compiled-to-native-code, development environment.

    The Visual Component Library (VCL) that is included with Delphi uses a predecessor to Avalon's XAML. By using a text or binary declarative "language", the form construction is taken out of the code. This "script" is attached to the executable as a resource. It can also be easily localized by providing an alternative script.

    Avalon is clearly an evolutionary step along this same path, but I would certainly *not* characterize it as "revolutionary."

    Yes, I work for Borland. Yes, I'm one of the original developers that designed and built Delphi. Delphi was launched on February 14, 1995 at the Software Development West conference in silicon valley.

    If you look closely, and resist the urge to revise history, you'll see that one of the primary architects behind .NET is Anders Hejlsberg... who was one of the original architects behind Delphi. Anders left Borland and helped produce J++ and WFC, then eventually C# and .NET. If you compare WinForms, WFC, nay Delphi's VCL, the similarities are... let's just say, striking.

    What I find interesting and, to be honest, somewhat frustrating, are the reactions when I state that "Delphi's been doing this since 1995." I can see them rolling their eyes, as if to say, "There's another of those Delphi crackpots who thinks they actually innovated something."

    In actual fact, we at Borland are extremely excited about the technologies that are coming out of Redmond.

    In fact, if you happen to *be* a Delphi programmer you need to keep your eye on the "Octane" project.. and if at all possible, attend the Borland Conference in San Jose, CA starting this weekend (Nov. 1, 2003).

    So I guess it *is* true that imitation is the highest form of flattery.

    Allen Bauer.
    Borland Software Corporation.
    RAD .NET IDE Architect.

    Wednesday, October 29, 2003

    Editor pair highlighting 


    Since one of my BorCon talks has been canceled, I will begin to post some of the content that was planned here. To get things started, here's one item that applies to C#Builder (and the upcoming Delphi 8, codenamed "Octane").

    Modifying which character pairs the IDE highlights:

    Insert standard disclaimer concerning editing your registry, here

    Open RegEdit and go to the following key:

    HKCU\Software\Borland\BDS\1.0\Editor\Source Options\Borland.EditOptions.XXXX\Pair Table

    Under the above key there are string entries formatted as comma separated values, for instance the "(* *)" pair in the "Borland.EditOptions.Pascal\Pair Table" key is represented as:

    0,1,2,(*,*)

    The meanings of these values are, in order:

    Nestable = 0 - No, 1 - Yes, 2 - Maybe
    ImpliedDir = 0 - No, 1 - Yes
    CharCount = 1 or 2 only
    Starting string = 1 or 2 char string
    Ending string = 1 or 2 char string

    So to create non-nestable, implied direction pair for, say <% and %> it would look like this:

    0,1,2,<%,%>

    So if you don't want to highlight the quote characters since they have no implied direction and will often highlight strangely, delete the 0,0,1,',' and 0,0,1,"," entries and those pairs won't display as match characters. Note that this will also disable the Ctrl-Q+[ and Ctrl-Q+] functionality for those characters.

    Tuesday, October 28, 2003

    Talks canceled 


    Due to product scheduling constraints, one of my BorCon talks has been cancelled. The "IDE Spelunking" talk will not take place on Tuesday, November 4 as planned. The Open Tools API talk is also in danger of being canceled as well. This stinks... I'll also not going to be able to be there very much either... Even though it is less than 30 minutes from Borland.

    Sunday, October 26, 2003

    Borland at this year's Microsoft PDC 


    Marco Russo - Borland at PDC

    It seems that some folks are certainly noticing the conspicuous placement of Borland at this year's Microsoft PDC. And, since BorCon is after MS' PDC, there'll be a lot of continued buzz... You don't want to miss it.

    Saturday, October 25, 2003

    Managed code gotcha's... 


    .NET Framework Security: Using Win32 and Other Libraries (Working with C#)

    Just learned a little lesson when working with managed code and P/Invoke. If you are providing a delegate as a callback to a P/Invoke'd Windows API function, make absolutely sure you hold a reference to that delegate for as long as that Windows API needs to call it... ;-) Since the CLR doesn't track references to things that travel off into the unmanaged nether-world, it will blithely garbage collect your delegate. This promptly hangs your unsuspecting API out to dry (think RegisterClass and CreateWindowEx). The absolutely insidious thing about all this is that it will work.. for a while. So take my advice, the oven is hot; wear your oven mitts...

    For all the time I've spent working with managed code, COM-interop, and P/Invoke, you'd think I'd know this stuff... But then again, I'm no Don Box, ChrisAn, or Lutz Roeder, et. al.... they've had the luxury of being exposed to this for a few more years ;-) Eventually, this stuff will seep through the several inches of solid rock and touch some grey-matter someplace...

    Disclaimer:
    The opinions expressed here are mine. They should in no way be construed as being the opinion of my employer, Borland Software Corp. If you actually think that my opinions are a reflection of Borland, then I have a bridge I can sell you.

    Subscribe to my RSS feed.

    This page is powered by Blogger. Isn't yours?