为了帮助我们模块化单体应用程序,我们正在设置用于调试构建的软件包,同时仍编译为单个 exe 用于发布构建。
我们的一个包(EAUtils)包含一个现在正在生产的单元[DCC Error] E2201 Need imported data reference ($G) to access 'SMsgDlgWarning' from unit 'SystemUtils'
。
这发生在构建 EAUtils 包本身时。我还没有构建依赖于 EAUtils 的软件包。EAUtils 仅依赖于 rtl/vcl 包和我为 Jedi WinApi 单元创建的包。
这是以下行的结果:
// 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;
更具体地说,这是引用SMsgDlgWarning
、和的结果SMsgDlgError
,它们都在 中声明。SMsgDlgInformation
SMsgDlgConfirm
Vcl.Const
请注意,当我们构建单个可执行文件时,此代码编译不会出错。
作为一种优化手段,我们的包含文件确实包含{$IMPORTEDDATA OFF}
,因为这允许更快地访问(全局)变量和常量。请参阅http://hallvards.blogspot.com/2006/09/hack13-access-globals-faster.html。
根据有关错误的文档(http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/cm_package_varref_xml.html)这是原因,它说“为了缓解问题,它通常最容易打开 $IMPORTEDDATA 开关并重新编译产生错误的单元。”
因此,我已经{$IMPORTEDDATA ON}
在我们的包含文件中进行了设置,并通过在项目选项部分中将设置Use imported data references
为 true 来确保。Delphi Compiler | Compiling | Debugging
不幸的是,与文档相反,这并没有缓解问题。即使直接在有问题的代码上方设置此编译器指令并重新构建包也不能消除错误。
我还需要做什么来解决这个 E2201 错误?不确定,但 SMsgDlgWarning 及其朋友是资源字符串可能很重要?