29

どうやら、Delphi(任意のバージョン)は安全な例外ハンドラー(VisualStudioの/SAFESEHスイッチ)をサポートしていません。これにより、Windows8でWindowsデスクトップアプリ認定キットを使用すると警告が表示されます。Windows8デスクトップアプリの認定要件ごとに、次のようになります。

安全な例外処理を確実にするために、アプリは/SafeSEHフラグを使用してコンパイルする必要があります

明らかに、Delphiにはこのスイッチがないため、実行できません。私の質問は次のとおりです。

  1. キットには警告のみが表示されますが(失敗しない)、これは「必須」の要件であるため、今日のDelphiアプリはWindows 8で認定できず、Windowsアプリストアに含めることができないという私の理解は正しいですか?

  2. SafeSEHテーブルをコンパイル後に何らかの方法でPEファイルに追加できますか(たとえば、マップファイルまたはデバッグシンボルから必要な情報を抽出する)、またはこれに対するコンパイラ/リンカーのサポートが絶対に必要であるため、Embarcaderoがこの機能を実装するまで待つ必要がありますか?

明確にするために、私のアプリケーションはWindows 32ビットデスクトップアプリケーション(64ビット互換)であり、 Metroアプリケーションではありません

4

2 に答える 2

3

質問 1 にはお答えできません。しかし、 mustという言葉を使用することで、ルールがオプションであるという意味になるとは考えにくいと思います。

質問 2 については、コンパイラ/リンカーからのサポートが必要です。これを PE 編集後リンク ツールでバック フィットすることは合理的に期待できません。次のコードを検討してください。

try
  Beep;
except
  on E: Exception do
    Writeln(E.ClassName, ': ', E.Message);
end;

コンパイラは次を出力します。

Project1.dpr.11: try
0041C3AA 33C0             xor eax,eax
0041C3AC 55               push ebp
0041C3AD 68C9C34100       push $0041c3c9 // exception handler is at $0041c3c9
0041C3B2 64FF30           push dword ptr fs:[eax]
0041C3B5 648920           mov fs:[eax],esp
Project1.dpr.12: Beep;
0041C3B8 6A00             push $00
0041C3BA E8E1CEFEFF       call MessageBeep
0041C3BF 33C0             xor eax,eax
0041C3C1 5A               pop edx
0041C3C2 59               pop ecx
0041C3C3 59               pop ecx
0041C3C4 648910           mov fs:[eax],edx
0041C3C7 EB59             jmp $0041c422
0041C3C9 E97291FEFF       jmp @HandleOnException
0041C3CE 0100             add [eax],eax
0041C3D0 0000             add [eax],al
0041C3D2 E42F             in al,$2f
0041C3D4 41               inc ecx
0041C3D5 00DA             add dl,bl
0041C3D7 C3               ret 
0041C3D8 41               inc ecx
0041C3D9 00A3D83E4200     add [ebx+$00423ed8],ah
Project1.dpr.15: Writeln(E.ClassName, ': ', E.Message);
........

さて、実際の例外ハンドラはHandleOnExceptionに実装されていSystem.pasます。ただし、スタックにプッシュされるアドレスは、ブロック$0041c3c9を含むコードにローカルなアドレスです。try/exceptつまり、SafeSEH PE セクションを作成するにtry/exceptは、コード内ですべての場所を特定する必要があります。それは明らかに実現可能ですが、扱いやすいとは思いません。

x86 コンパイラの SEH 例外ハンドラーは_HandleXXXSystem.pas. その場合、これらの関数だけをリストする PE セクションをリンク後のステップとして追加するのは簡単です。ただし、すべてtry/exceptの例外が独自のローカル例外ハンドラを持っているため、コンパイラの作成者だけが SafeSEH PE セクションを追加することを現実的に望むことができると私は信じています。

私が見る限りSafeSEH、x86 Windows コンパイラのサポートを要求する QC レポートはありません。QC レポートと公式のサポート ケースを記録することをお勧めします。

更新: @haimg によくやっ

于 2012-07-31T13:23:38.543 に答える
0

Delphiのアプリケーションが認定されない理由は他にもあります

http://delphitools.info/2012/08/23/why-no-native-winrt-support-in-delphi-xe3/

于 2012-12-26T15:14:35.777 に答える