Watch, Follow, &
Connect with Us

Team Japan

Delphi 2010: 新機能 delayed ディレクティブ

高橋(智)です。
今日は、Delphi 2010 のコンパイラに追加された一見地味でありながら、魅力的な機能を紹介しようと思います。すでにAllenさんがblogで紹介されていますが、DLLの関数呼び出しコードにおけるそのエントリポイントの解決を、実際の呼び出し時まで遅延させる新しいディレクティブ「 delayed; 」が追加されました。
[Procrastinators Unite… Eventually!]
http://blogs.embarcadero.com/abauer/2009/08/25/38894
この「 delayed; 」の簡単な使い方は上のAllenさんのblogを見ていただくとして、以下、私が以前にteamjのblogで書いた
[InitializeCriticalSectionEx]
http://blogs.embarcadero.com/teamj/2009/05/25/461/
のコードをDelphi 2010で書き直してみようと思います。
そのblogでは、WindowsXPやWindows2000の「kernel32.dll」には搭載されていない「InitializeCriticalSectionEx」というWin32APIを呼び出しています。どのOSでも「.EXEファイルが起動できるよう」にするために、WindowsVista/2008/7の場合には「LoadLibrary/GetProcAddress」を使って動的に「InitializeCriticalSectionEx」のエントリポイントを取得しています。
それでは、「 delayed; 」を使ったコードに書き直してみます。一気にスッキリしたコードになりました。「InitializeCriticalSectionEx(css[i], 0, CRITICAL_SECTION_NO_DEBUG_INFO)」のコードは通常の関数呼び出しに見えますが、実際には1回目の呼び出し時に「LoadLibrary/GetProcAddress」が利用され、2回目以降は1回目の処理をスキップして、「InitializeCriticalSectionEx」が呼び出されるようになります。このようなコードはDelphiコンパイラが自動で追加してくれます。
-------------------------------------
function InitializeCriticalSectionEx(var lpCriticalSection: TRTLCriticalSection;
  dwSpinCount: DWORD; Flags: DWORD): BOOL; stdcall; external ‘kernel32.dll’ name ‘InitializeCriticalSectionEx’ delayed;
const CRITICAL_SECTION_NO_DEBUG_INFO = $01000000;

procedure TForm5.Button1Click(Sender: TObject);
var
  i: Integer;
  css: array of TRTLCriticalSection;
  Vista_2008_Win7: Boolean;
begin
  SetLength(css, 1000000);

  Vista_2008_Win7 := CheckWin32Version(6, 0); // Check OS Version
  for i := 0 to Length(css)-1 do
  begin
    if Vista_2008_Win7 then
      InitializeCriticalSectionEx(css[i], 0, CRITICAL_SECTION_NO_DEBUG_INFO)
    else
      InitializeCriticalSection(css[i]);
  end;

  for i := 0 to Length(css)-1 do
  begin
    EnterCriticalSection(css[i]);
    // …
    LeaveCriticalSection(css[i]);
  end;

  for i := 0 to Length(css)-1 do
    DeleteCriticalSection(css[i]);
end;
-------------------------------------

なお、C++Builderには昔から同様の機能が搭載されていまして、以前のデベロッパーキャンプでは
[リンカ「DLL遅延ロードオプション」の意外な使い道]
http://edn.embarcadero.com/jp/article/images/37640/a3.pdf
として紹介しました。しかし、C++Builderの場合には.DLL全体(全関数)を遅延ロードすることになりますし、kernel32.dllのようなシステムDLLは遅延ロードの対象にすることはできません。
以上のように、個別の関数だけ遅延ロードできるようにしたDelphi 2010のコンパイラはとても魅力的だと思います。また、上のC++Builderのセッション資料で解説している「VCLのGUI機能を内蔵するDLLの初期化問題」にも対応できるようになるのではないか? と思います。この件については時間があれば解説したいと思います。

Posted by Tomohiro Takahashi on August 26th, 2009 under C++, Delphi |



One Response to “Delphi 2010: 新機能 delayed ディレクティブ”

  1. Twitter Trackbacks for Team Japan » Delphi 2010: 新機能 delayed ディレクティブ [embarcadero.com] on Topsy.com Says:

    [...] Team Japan » Delphi 2010: 新機能 delayed ディレクティブ blogs.embarcadero.com/teamj/2009/08/26/770 – view page – cached Embarcadero Developer Network Embarcadero Developer Network Communities Articles Blogs Resources Downloads Help Embarcadero Blogs » Team Japan — From the page [...]

Leave a Comment



Server Response from: BLOGS1