为了帮助我们模块化整体应用程序,我们正在设置用于调试版本的包,同时仍编译为用于发布版本的单个 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
来双重确定为真Delphi Compiler | Compiling | Debugging
项目选项部分。
不幸的是,与文档相反,这并没有缓解问题。即使直接在有问题的代码上方设置此编译器指令并重建包也无法消除错误。
我还需要做什么才能解决此 E2201 错误? 不确定,但 SMsgDlgWarning 及其 friend 是资源字符串可能很重要?
最佳答案
错误消息,恕我直言,具有误导性,它是用 $G-
编译的 Vcl.Consts
,导致了问题。
作为解决方法,您可以使用如下内容:
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;
也可以使用 const 字符串数组进行编译(尽管它会破坏本地化):
const
Captions: array[TMsgDlgType] of string = (SMsgDlgWarning, SMsgDlgError, SMsgDlgInformation, SMsgDlgConfirm, '');
或者您可以使用 {$G+}
构建包含 Vcl.* 单元的自己的包,并使用它代替标准的 vcl
包。我更喜欢第一个解决方案;后者可能会在以后的部署中产生更多问题(所谓的“DLL hell ”)。
关于delphi - 使用运行时包构建时如何解决 "Need imported data reference",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10512504/