Friday, October 24, 2008

C++ Builder 2009 Compiler Bug Fixes... Finally!

Came across this today and found that CodeGear has finally fixed all the compiler bugs I've filed in 2005 (3 years ago). Heck, if you do a search for "Zach Saw", you'll find that one of the entries has a path to my "My Documents" ;)

Anyway, kudos to Embarcadero to let the team work on these C++ compiler bugs which turned most of us away to the clutches of Microsoft Visual Studio / C# back then. These compiler bugs were by no means trivial - they were so nasty that they simply rendered any effort to create a stable 24/7 server impossible.

With all these bugs fixed, C++ Builder would now be the definitive tool to create a proper server (especially versus C#) - low memory usage, blistering fast and it shares most of its the design patterns with .NET (in fact, one would argue that C# is heavily inspired by Delphi / C++ Builder). I spent just 3 days writing a framework which is intimately similar to .NET's asynchronous IO design and its Control.BeginInvoke / Control.Invoke design. In case of the latter, I found that with C++, you get more type checking than you would with C# in passing parameters to the callback. In fact, even the return type for EndInvoke could be type checked with RTTI (during run-time unfortunately, but in any case, is automatic unlike .NET).

[ILINK32 Error] Fatal: Unable to open file .obj

If you have been playing around with Delphi packages compiled for C++ Builder in Borland Developer Studio or CodeGear RAD Studio, you'll have undoubtedly run into this error message. You could also run into that if you are not dealing with Delphi packages (e.g. using a run-time package, static library).

Let's start with Delphi packages.

What is suspicious is the way the linker reports the error - such as [ILINK32 Error] Fatal: Unable to open file MyComponent.obj. You search the entire hard drive for MyComponent.obj only to find the closest thing to be MyComponent.dcu, which is compiled in Delphi from MyComponent.pas. So how and where do you get MyComponent.obj?

The answer is, this .obj file is actually in a container with the extension of .LIB. If your package with MyComponent.pas is called MyPackage.bpl, then you need to look for MyPackage.lib. While an installed package should get automatically added to the default list of included packages when you create a new project file, it doesn't always happen (i.e. bug). All you have to do then is manually open up your current project file (.cbproj) in a text editor and add MyPackage.lib into the tag. Reload your project and you should be able to link successfully.

If you are not dealing with Delphi packages and you get that error message, that means you're trying to use a static library, or a run-time package (and some times even design-time package which are not dropped onto a form / data module). This could easily be fixed and is the expected way linkers work. There are 2 ways you can fix this:

1) Add the lib file to the project (I don't like this, as you rely on the user of the static library to remember to add the lib file every time they use it in a new project)
2) Add the following line to a header file which is guaranteed to be included when the static library is used:
#pragma comment(lib, "your library name.lib")

That's it.

I haven't tried C++ Builder 2009, but I hope CodeGear have found a better way to do this. Actually, I'd suggest that they simply make all Delphi compiler generated C++ Builder files include that #pragma comment(lib, ...) line so that we never have to muck around with the .cbproj files any more. In fact, this would also mean that there will be no annoying messages that prompts you to remove packages you don't need when you create and try to save a new project.

Wednesday, October 8, 2008

BUG: April 08 Hotfix for CodeGear RAD Studio Skips Update

I've run into yet another Borland / CodeGear bug - this time with the April 08 Hotfix installer. It says it has successfully applied the Hotfix but it really hasn't and you would have noticed that on the installation summary screen, it says "Current Hotfix Level: 1", instead of 0.

What happened?

Well, to begin with, you'll always run into this issue everytime you have applied this hotfix and then reinstalled CodeGear RAD Studio (i.e. uninstall and reinstall from the original DVD). The registry settings for the HotfixLevel doesn't get cleared.

Workaround is simple. Go to your registry (plenty of registry actions with Borland / CodeGear - I'm sure all of you are used to it by now), and open the following key:


(Note: Assuming you installed RAD Studio for all users. If you've installed it for current user only, look into HKEY_CURRENT_USER and look for this key as well)

In there, you'll find an entry called HotfixLevel and it'll have 1 as its value. Change it to 0 and restart the hotfix. It now correctly detect that it hasn't updated the files and proceed to update them.

Delphi Packages not appearing in C++ Builder personality

One of the new features in CodeGear RAD Studio 2007 (actually Borland Developer Studio which is the 2006 version of RAD Studio) is the ability to get the Delphi compiler / linker to generate all the files required by C++ Builder (.hpp, .obj, .lib etc.) for a Delphi package, without having to create the equivalent C++ Builder package.

Unfortunately, there's one ugly bug that has plagued this feature - you may find that the components in the package that you've installed does not come up in the designer's Tool Palette. This bug was first reported by yours truly against BDS 2006 and it appears that it hasn't been and won't be fixed even for RAD Studio 2009. That's more than 3 years since I've reported it in QC! Wow!

If you have left all settings to the default when you create a package in Delphi (which you most likely will), you will find that the components you've registered in the package won't appear in a C++ Builder project. That is simply because you have not specifically told the linker to "Generate all C++Builder files". So you would go back to the Delphi package and select that option in the Linker output and recompile / reinstall. This time, however, you would expect the installed components to appear in the Tool Palette when you try to use it in C++ Builder... Surprise surprise, it's not there!

It's as though once the IDE has decided that it is a Delphi-only package, it will remain a Delphi-only package forever. Note that if you uninstall and recreate and then reinstall the entire package, it will still be invisible to C++ Builder - that is, until you've renamed the package. That's because the IDE remembers the package name!

The other cleaner workaround would be to go to your registry via Regedit.exe and remove all the following entries to your package (say, MyPackage.bpl).

HKEY_CURRENT_USER\Software\Borland\BDS\5.0\Known Packages\
Look for the entry with [path]\MyPackage.bpl and remove it

HKEY_CURRENT_USER\Software\Borland\BDS\5.0\Package Cache\
Look for the key called MyPackage.bpl and remove the entire sub-key

Look for the key called MyPackage.bpl and remove the entire sub-key

Remember to first shut down CodeGear RAD Studio before changing the registry keys. Once you have removed the entries, restart RAD Studio and this time, remember to select "Generate all C++Builder files" for all build configurations (e.g. Debug and Release) before you install the Delphi package.

And in the future, keep in mind to always set the linker to "Generate all C++Builder files" or set that as your default for all build configurations.

ps. Yup, they haven't rebranded it to CodeGear in the registry - it's still Borland as we know it! :)

Wednesday, October 1, 2008

QuickPHP v1.4 Adds Apache Mod Capabilities

Those who are familiar with Apache mods will welcome this new addition to QuickPHP. What sets QuickPHP apart though, is that it uses PHP itself to implement the mods.
I've detailed its inner workings before on this blog here.
You can download QuickPHP here and read the mod documentation here.
While I've made the interface to create mods available, there isn't any mods available yet. This is the time QuickPHP could really use your contributions. Someone to write the equivalent of mod_rewrite, mod_log_referrer, mod_log etc. in PHP. Anything that might be useful to you, is potentially useful to others too. So don't be shy to contribute your code in the forum!