How to solve the "Need for imported data reference" when creating runtime packages

To help us modulate a monolithic application, we are in the process of creating packages for use in debug builds, while still compiling one instance for release.

One of our packages (EAUtils) contains a block that now produces [DCC Error] E2201 Need imported data reference ($G) to access 'SMsgDlgWarning' from unit 'SystemUtils' .

This happens when creating the EAUtils package itself. I am not going to create packages that are still dependent on EAUtils. EAUtils depends only on rtl / vcl packages and the package I created for Jedi WinApi blocks.

This is the 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; 

In particular, this is the result of the link SMsgDlgWarning , SMsgDlgError , SMsgDlgInformation and SMsgDlgConfirm , which are all declared in Vcl.Const .

Please note that this code compiles without errors when we create one executable file.

As an optimization tool, our include file contains {$IMPORTEDDATA OFF} , because it allows faster access to (global) variables and constants. See http://hallvards.blogspot.com/2006/09/hack13-access-globals-faster.html .

According to the error documentation ( http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/cm_package_varref_xml.html ) this is the reason and it says: "To alleviate the problem, it, as a rule, the easiest way is to turn on the $ IMPORTEDDATA switch and recompile the device that generates the error.

So, I installed {$IMPORTEDDATA ON} in our include file and made it doubly sure by setting Use imported data references to true in the Delphi Compiler | Compiling | Debugging Delphi Compiler | Compiling | Debugging Delphi Compiler | Compiling | Debugging project parameters.

Unfortunately, contrary to the documentation, this did not alleviate the problem. Even setting this compiler directive directly above the violating code and redoing the package failed to fix the errors.

What else do I need to do to resolve this error E2201? Not sure, but it may be important that SMsgDlgWarning and his friends are resource strings?

+4
source share
1 answer

The error message, IMHO, is misleading, it is Vcl.Consts , which was compiled using $G- and that causes 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 const array of string arrays, too (although it breaks localization):

 const Captions: array[TMsgDlgType] of string = (SMsgDlgWarning, SMsgDlgError, SMsgDlgInformation, SMsgDlgConfirm, ''); 

or you can create your own package containing Vcl. * units, with {$G+} and use this instead of the standard vcl package. I prefer the first solution; the latter can potentially create more deployment problems (the so-called "addon dll").

+8
source

Source: https://habr.com/ru/post/1411465/


All Articles