加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何在使用运行时包构建时解决“需要导入的数据引用”

发布时间:2020-12-15 09:34:02 所属栏目:大数据 来源:网络整理
导读:为了帮助我们模块化单片应用程序,我们正在设置用于调试版本的包,同时仍然编译为发布版本的单个exe. 我们的一个软件包(EAUtils)包含一个现在正在生成[DCC错误]的单元E2201需要导入数据引用($G)才能从单元’SystemUtils’访问’SMsgDlgWarning’. 在构建EAUtil
为了帮助我们模块化单片应用程序,我们正在设置用于调试版本的包,同时仍然编译为发布版本的单个exe.

我们的一个软件包(EAUtils)包含一个现在正在生成[DCC错误]的单元E2201需要导入数据引用($G)才能从单元’SystemUtils’访问’SMsgDlgWarning’.

在构建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中声明.

请注意,当我们构建单个可执行文件时,此代码编译时没有错误.

作为一种优化方法,我们的include文件确实包含{$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开关并重新编译产生错误的单元.”

所以,我在我们的include文件中设置了{$IMPORTEDDATA ON},并通过在Delphi编译器中将使用导入的数据引用设置为true来加倍确定.编译|调试项目选项部分.

不幸的是,与文档相反,这并没有缓解这个问题.即使将此编译器指令直接设置在违规代码上方并重建包也不会删除错误.

我还需要做些什么来解决这个E2201错误?
不确定,但SMsgDlgWarning及其朋友是资源字符串可能很重要吗?

解决方法

错误消息是,恕我直言,误导,它是Vcl.Consts,已用$G-编译,这导致了问题.
作为一种解决方法,您可以使用以下内容:

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,SMsgDlgInformation,SMsgDlgConfirm,'');

或者您可以使用{$G}构建自己的包含Vcl.*单元的包,并使用它而不是标准的vcl包.我更喜欢第一种解决方案;后者可能会在以后部署时产生更多问题(所谓的“DLL地狱”).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读