6

モノリシックアプリケーションのモジュール化を支援するために、リリースビルド用に単一のexeにコンパイルしながら、デバッグビルドで使用するパッケージをセットアップ中です。

パッケージの1つ(EAUtils)には、現在生産中のユニットが含まれています[DCC Error] E2201 Need imported data reference ($G) to access 'SMsgDlgWarning' from unit 'SystemUtils'

これは、EAUtilsパッケージ自体をビルドするときに発生します。私はまだEAUtilsに依存するパッケージを構築することに興味がありません。EAUtilsは、rtl/vclパッケージとJediWinApiユニット用に作成したパッケージにのみ依存します。

これは次の行の結果です。

// 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であり、これらはすべて。で宣言されています。SMsgDlgInformationSMsgDlgConfirmVcl.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とその友人がリソース文字列であることは重要かもしれません。

4

1 に答える 1

9

エラーメッセージは、IMHO、誤解を招くものであり、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, SMsgDlgError, SMsgDlgInformation, SMsgDlgConfirm, '');

{$G+}または、標準vclパッケージの代わりにそれを使用して、Vcl.* ユニットを含む独自のパッケージを作成することもできます。私は最初の解決策を好みます。後者は、後で展開時にさらに多くの問題を引き起こす可能性があります (いわゆる「DLL 地獄」)。

于 2012-05-09T09:52:54.437 に答える