Resolving linker errors when using TRegistry

By: mykle hoban

Abstract: This article describes how to get rid of linker errors that pop up when deriving a class from TRegistry (esp. with regards to the ChangeKey function)

Question

Why am I getting unresolved external errors in the function ChangeKey when trying to link a class derived from TRegistry?

[Linker Error] Unresolved external '__fastcall Registry::TRegistry::ChangeKey(int, const System::AnsiString)' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER5\LIB\RELEASE\VCLE50.LIB|_t_Regis

Answer

This problem is very similar to one documented on our site regarding TMetafileCanvas. It is caused by a bug in the VCLE50.lib library, a library that allows the VCL (Pascal) library to be used in C++. In Pascal, Handles are treated as integer (unsigned), and in C++, they are treated as void pointers. The linker error was is given because the library was looking for a void pointer and passing in an int, which is incompatible with the unsigned that is actually in the VCL.

One work around is to edit the VCL header file Registry.hpp, changing the type of the first parameter of the ChangeKey function from 'HKEY' to 'unsigned int'. After this change, calling ChangeKey will require typecasting the first parameter to unsigned int. While this works, it is not the best solution. When the bug causing this problem is fixed, the typecast will no longer be necessary and will cause compiler errors when the source is recompiled.

A much better fix is to change the actual library so that the bug no longer occurs. This is not normally a very wise course of action because it can actually corrupt core VCL libraries and severely harm C++Builder, but in this case, the fix has been tested and it works. To undo this bug, simply copy and paste the code below into notepad and name the file RegFix.asm. Then, in a command shell (DOS box), run the following:

tasm32 /ml RegFix.asm
<copy RegFix.obj into $(BCB)\lib\debug and $(BCB)\lib\release>
tlib /C vcle50.lib +RegFix.obj (do in both \lib and \release)

This will patch the library and the error will cease.


       .386
       .MODEL FLAT
       .CODE

       EXTRN     @Registry@TRegistry@ChangeKey$qqruix17System@AnsiString:NEAR
_TEXT  segment   dword public 'CODE' use32
       @Registry@TRegistry@ChangeKey$qqrix17System@AnsiString    segment virtual
       @@Registry@TRegistry@ChangeKey$qqrix17System@AnsiString  PROC
       jmp       @Registry@TRegistry@ChangeKey$qqruix17System@AnsiString
       @@Registry@TRegistry@ChangeKey$qqrix17System@AnsiString  ENDP
       @Registry@TRegistry@ChangeKey$qqrix17System@AnsiString    ends
_TEXT  ends

       END

Server Response from: ETNASC04