To help us modularize a monolithic application, we are in the process of setting up packages for use in debug builds, while still compiling to a single exe for release builds.
One of our packages (EAUtils) contains a unit that is now producing [DCC Error] E2201 Need imported data reference ($G) to access 'SMsgDlgWarning' from unit 'SystemUtils'
.
This happens when building the EAUtils package itself. I am not into building packages that depend on EAUtils yet. EAUtils only depends on rtl/vcl packages and a package I created for the Jedi WinApi units.
This is a result of the lines:
// This is a TaskDialog override, with the same args as the old MessageDlg.
function TaskDialog(const aContent: string; const Icon: HICON = 0;
const Buttons: TTaskDialogCommonButtonFlags = TDCBF_OK_BUTTON): Integer;
const
Captions: array[TMsgDlgType] of Pointer = (@SMsgDlgWarning, @SMsgDlgError, @SMsgDlgInformation, @SMsgDlgConfirm, nil);
var
aMsgDlgType: TMsgDlgType;
aTitle: string;
begin
aMsgDlgType := TaskDialogIconToMsgDlgType(Icon);
if aMsgDlgType <> mtCustom then
aTitle := LoadResString(Captions[aMsgDlgType])
else
aTitle := Application.Title;
More specifically this is a result of referencing SMsgDlgWarning
, SMsgDlgError
, SMsgDlgInformation
and SMsgDlgConfirm
, which are all declared in Vcl.Const
.
Please note that this code compiles without error when we are building a single executable.
As a means of optimization, our include file does contain {$IMPORTEDDATA OFF}
as this allows for faster access to (global) variables and constants. See http://hallvards.blogspot.com/2006/09/hack13-access-globals-faster.html.
According to the documentation on the error ( http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/cm_package_varref_xml.html ) this is the cause and it says "To alleviate the problem, it is generally easiest to turn on the $IMPORTEDDATA switch and recompile the unit that produces the error."
So, I have set {$IMPORTEDDATA ON}
in our include file and made doubly sure by setting the Use imported data references
to true in the Delphi Compiler | Compiling | Debugging
section of the project options.
Unfortunately, contrary to the documentation, this did not alleviate the problem. Even setting this compiler directive directly above the offending code and rebuilding the package did not remove the errors.
What else do I need to do to solve this E2201 error? Not sure, but it may be significant that SMsgDlgWarning and its friends are resource strings?
The error message is, IMHO, misleading, it's Vcl.Consts
which has been compiled with $G-
and that's causing the problem.
As a workaround, you can use something like this:
function Captions(AType: TMsgDlgType): Pointer;
begin
Result := nil;
case AType of
TMsgDlgType.mtWarning:
Result := @SMsgDlgWarning;
TMsgDlgType.mtError:
Result := @SMsgDlgError;
TMsgDlgType.mtInformation:
Result := @SMsgDlgInformation;
TMsgDlgType.mtConfirmation:
Result := @SMsgDlgConfirm;
end;
end;
Using a const array of string compiles, too (although it breaks localization):
const
Captions: array[TMsgDlgType] of string = (SMsgDlgWarning, SMsgDlgError, SMsgDlgInformation, SMsgDlgConfirm, '');
or you could build your own package containing Vcl.* units, with {$G+}
and use that instead of the standard vcl
package. I prefer the first solution; the latter can potentially create more problems later with deployment (so-called "DLL hell").
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With