MARUZEN&ジュンク堂書店 渋谷店で
プログラミングWindows 7 (amazon)/矢嶋聡著/日経BP/ISBN 978-4-82229-434-2/3,570円
を購入。
2011年4月28日
InterBase XE Update 2リリース
InterBase XE Update 2がリリースされています。バージョンは10.0.2.474となっています。
28298 InterBase XE Update 2 (10.0.2.477) 32-bit ToGo Edition, Windows
28301 InterBase XE 64-bit Update 2 (10.0.2.474) for Windows
28302 InterBase XE 32-bit Update 2 (10.0.2.474) for Windows
元ねたはTeam Japan » InterBase XE Update 2 日本語版(10.0.2.474) がリリースされました。
2011/04/30追記: InterBase XE Update 2 Readmeが公開されています。元ねたはSip from the Firehose : InterBase XE Update 2 is now available for download。
28298 InterBase XE Update 2 (10.0.2.477) 32-bit ToGo Edition, Windows
28301 InterBase XE 64-bit Update 2 (10.0.2.474) for Windows
28302 InterBase XE 32-bit Update 2 (10.0.2.474) for Windows
元ねたはTeam Japan » InterBase XE Update 2 日本語版(10.0.2.474) がリリースされました。
2011/04/30追記: InterBase XE Update 2 Readmeが公開されています。元ねたはSip from the Firehose : InterBase XE Update 2 is now available for download。
2011年4月27日
Delphi IDE Theme EditorがDelphi 5/6をサポート
RRUZ(Rodrigo Ruz)さんのDelphi IDE Theme EditorがバージョンアップしてDelphi 5/6のIDEをサポートするようになっています。
Added support for Delphi 5 and 6 in the Delphi IDE Theme Editor « The Road to Delphi – a Blog About Delphi Programming (mostly)
現時点(2011/04/27)の最新バージョンは1.0.0.136です。
Added support for Delphi 5 and 6 in the Delphi IDE Theme Editor « The Road to Delphi – a Blog About Delphi Programming (mostly)
現時点(2011/04/27)の最新バージョンは1.0.0.136です。
2011年4月26日
Delphi Certificate Programベータテスト
しばらく前に公式フォーラムでその存在がほのめかされていた"Delphi Certificate Program"ですが、Andreano Lanusseさんによるといよいよベータプログラムが始まるとのことです。
Delphi Certification Beta Program | Andreano Lanusse Blog | Technology and Software Development
Delphi Certificate ProgramとはDelphiプログラマのスキルレベルの認定を行うもので、最初はDeveloper、Masterの2レベルが準備されるとのことです。ベータプログラムではまずMasterレベルのテストが行われ、"Delphi Master"認定テストの内容の検証を目標としています(ベータテスター自身の合否ではなく)。ベータテストの対象は2年以上のDelphi 7以降のプログラマで、問題は以下の知識分野でグループ分けされています。
日本語バージョンは登場するのでしょうか?とりあえず連休中にチャレンジしてみようかな…。
Delphi Certification Beta Program | Andreano Lanusse Blog | Technology and Software Development
Delphi Certificate ProgramとはDelphiプログラマのスキルレベルの認定を行うもので、最初はDeveloper、Masterの2レベルが準備されるとのことです。ベータプログラムではまずMasterレベルのテストが行われ、"Delphi Master"認定テストの内容の検証を目標としています(ベータテスター自身の合否ではなく)。ベータテストの対象は2年以上のDelphi 7以降のプログラマで、問題は以下の知識分野でグループ分けされています。
- Delphi XE Interface and Configuration
- Delphi VCL and RTL
- Delphi Language and Object-Oriented Programming
- Component Design Basics
- Working with Components
- Database Concepts/Data Access Techniques
- dbExpress
- DataSnap
- Writing DLLs and Packages
- Libraries and Packages
- Windows Concepts
- Internet Programming
- XML
日本語バージョンは登場するのでしょうか?とりあえず連休中にチャレンジしてみようかな…。
2011年4月25日
RAD StudioのIDEでConsolasとMeiryoKe Consoleを使う(Windows 7)
前回の続きでWindows 7の場合です。Windows XP/Vistaで使用できるメイリオはVer5.00でしたが、Windows 7に付属しているメイリオはVer6.02です。とはいっても手順としてはあまり変わらず、作業フォルダに"meiryo.ttc"と"meiryob.ttc"をコピーし、
ブログ内記事で取りあげたソフト・ファイルのDL情報 『ことば・その周辺』
からダウンロードした"meiryoKe_gen_6.02rev1.zip"を同じ作業フォルダに展開し、"meiryoKe_gen_6.02rev1.exe"を実行し、生成された"meiryoKe_602r1.ttc"と"meiryoKeB_602r1.ttc"を"meiryoKe.ttc"と"meiryoKeB.ttc"にリネームし(これは好みで)、右クリック→インストールでフォントフォルダにコピーします。あとはWindows XP/Vistaの場合と同様にレジストリエディタで
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
を開き、新規作成で複数行文字列値を作成し、名前を"Consolas"として内容を
として設定して再起動します(Windows XP/Vistaと異なりフォントファイルがTTC形式なのでレジストリ上の指定方法も異なります)。あとはRAD StudioのIDEで使用するフォントを"Consolas"にするだけです(ClearTypeのチューニングはコントロールパネル→"ディスプレイ"→"ClearTypeテキストの調整"→"ClearTypeテキストチューナ"で)。
ブログ内記事で取りあげたソフト・ファイルのDL情報 『ことば・その周辺』
からダウンロードした"meiryoKe_gen_6.02rev1.zip"を同じ作業フォルダに展開し、"meiryoKe_gen_6.02rev1.exe"を実行し、生成された"meiryoKe_602r1.ttc"と"meiryoKeB_602r1.ttc"を"meiryoKe.ttc"と"meiryoKeB.ttc"にリネームし(これは好みで)、右クリック→インストールでフォントフォルダにコピーします。あとはWindows XP/Vistaの場合と同様にレジストリエディタで
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
を開き、新規作成で複数行文字列値を作成し、名前を"Consolas"として内容を
meiryoKe.ttc,meiryoKe_Console
mingliu.ttc,MingLiU
SimSun.TTC,SimSun
gulim.ttc,GulimChe
として設定して再起動します(Windows XP/Vistaと異なりフォントファイルがTTC形式なのでレジストリ上の指定方法も異なります)。あとはRAD StudioのIDEで使用するフォントを"Consolas"にするだけです(ClearTypeのチューニングはコントロールパネル→"ディスプレイ"→"ClearTypeテキストの調整"→"ClearTypeテキストチューナ"で)。
2011年4月23日
IDE Fix Pack 4.1 RC/DelphiSpeedUp 3.1 RCリリース
Andreas HausladenさんのIDE Fix Pack 4.1 RCとDelphiSpeedUp 3.1 RCが公開されています。これは先日リリースされたIDE Fix Pack 4.0/DelphiSpeedUp 3.0でコードエディタのタブを閉じたときにアクセス違反が状況によっては発生する、という問題があるためとのことです。Delphi 6/2006については未テストとのことですので、使用する際は注意が必要です。
IDE Fix Pack 4.1 RC, DelphiSpeedUp 3.1 RC | Andy’s Blog and Tools
IDE Fix Pack 4.1 RC, DelphiSpeedUp 3.1 RC | Andy’s Blog and Tools
2011年4月22日
Project "Cooper"ベータ情報
RemObjectsからCooperのベータ版の情報とビデオが公開されています。
“Cooper” Beta details « RemObjects Blogs
Oxygene on RemObjects TV | RemObjects Software
とりあえずは順調に進んでいるということでしょうか。
“Cooper” Beta details « RemObjects Blogs
Oxygene on RemObjects TV | RemObjects Software
とりあえずは順調に進んでいるということでしょうか。
RAD StudioのIDEでConsolasとMeiryoKe Consoleを使う(Windows XP/Vista)
RAD StudioなどのIDEで使用するフォントは英語圏ではConsolasとだいたい相場が決まっている(個人的な感想です)のですが、日本語を使う、となると実に微妙な状況です。特にWindows XP以降のClearType (ja)を効かせた設定にしたい場合、選択肢はメイリオかそれなりに高価な商用フォントしかありません(商用フォントを買えばもちろん幸せになれそうですが)。メイリオはご存知のとおりWindows XPまでのフォントとはメトリクスが大きく異なり、更に英数字が等幅ではないためIDE用のフォントとしてはあまり適しているとはいえません。そこでメイリオのフォントデータをパッチで改変することで従来の(MS ゴシック/MS Pゴシック/MS UIゴシックシリーズの)メトリクスに近いMeiryoKe系フォントを生成し、これをConsolasにフォントリンクすることで、Consolas + MeiryoKe_ConsoleをIDEで使用する、という方法を試してみたのでメモ。まずはWindows XP/Vista(メイリオ Ver5.00)環境の手順を。
注意事項: MeiryoKeはライセンス的に相当グレーです。あくまで自己責任で。特にMeiryoKeのフォントファイルそのものを配布するのは明らかにまずいのでご注意ください。
Windows VistaにはConsolas、メイリオとも含まれていますが、Windows XPにはデフォルトではこれらのフォントが存在しませんので、まずこれらを入手します。Microsoft Visual Studio 2005/2008のどのSKUでもよいので(Express Editionでよい)インストールし、次に
Download details: Consolas Font Pack for Microsoft Visual Studio 2005 or 2008
をダウンロード、インストールします。続いて
ダウンロードの詳細 : Windows XP 向け ClearType 対応日本語フォント
(こちらはメイリオ)をダウンロード、インストールします。
材料が揃ったところで次にMeiryoKeの生成です。フォントフォルダから作業用フォルダに"meiryo.ttc"と"meiryob.ttc"をコピーし、
ブログ内記事で取りあげたソフト・ファイルのDL情報 『ことば・その周辺』
からリンクされているページで"meiryoKe_gen_5.00rev1.zip"と"meiryoKeConsole_gen_5.00rev1.zip"をダウンロードし、これも作業フォルダに展開します。次に"meiryoKe_gen_5.00rev1.exe"と"meiryoKeConsole_gen_5.00rev1.exe"を実行し、生成されたフォントファイル("meiryoKeGothic.ttc"、"meiryoKeGothicB.ttc"、"meiryoKeConsole.ttf")を右クリック→インストールでフォントフォルダにコピーします。
これでConsolas、MeiryoKe_Consoleを使用できるようになりましたが、IDEで指定できるフォントは通常1つだけです。そこでConsolasにフォントリンクを設定し、Consolasに存在しないコードポイントに対してMeiryoKe_Consoleを使用するようにします。
レジストリエディタで
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
を開き、新規作成で複数行文字列値を作成し、名前を"Consolas"として内容を
(普通に使用するならmeiryoKeConsole.ttfだけで十分ですが)として再起動します。これでIDEで使用するフォントをConsolasに設定することでConsolas + MeiryoKe_Consoleの組み合わせになります。ただしWindows XPの場合はClearTypeを有効にし、さらに
Microsoft Typography - ClearType Tuner PowerToy
からClearType Tunerをダウンロード、インストールして好みの状態に調整したほうがいいでしょう。このあたりについては@ITの
Windows XPの正体 : 文字表示を滑らかにする新技術「ClearType」
ClearTypeフォントの表示方法を調整する - @IT
あたりが参考になります。
注意事項: MeiryoKeはライセンス的に相当グレーです。あくまで自己責任で。特にMeiryoKeのフォントファイルそのものを配布するのは明らかにまずいのでご注意ください。
Windows VistaにはConsolas、メイリオとも含まれていますが、Windows XPにはデフォルトではこれらのフォントが存在しませんので、まずこれらを入手します。Microsoft Visual Studio 2005/2008のどのSKUでもよいので(Express Editionでよい)インストールし、次に
Download details: Consolas Font Pack for Microsoft Visual Studio 2005 or 2008
をダウンロード、インストールします。続いて
ダウンロードの詳細 : Windows XP 向け ClearType 対応日本語フォント
(こちらはメイリオ)をダウンロード、インストールします。
材料が揃ったところで次にMeiryoKeの生成です。フォントフォルダから作業用フォルダに"meiryo.ttc"と"meiryob.ttc"をコピーし、
ブログ内記事で取りあげたソフト・ファイルのDL情報 『ことば・その周辺』
からリンクされているページで"meiryoKe_gen_5.00rev1.zip"と"meiryoKeConsole_gen_5.00rev1.zip"をダウンロードし、これも作業フォルダに展開します。次に"meiryoKe_gen_5.00rev1.exe"と"meiryoKeConsole_gen_5.00rev1.exe"を実行し、生成されたフォントファイル("meiryoKeGothic.ttc"、"meiryoKeGothicB.ttc"、"meiryoKeConsole.ttf")を右クリック→インストールでフォントフォルダにコピーします。
これでConsolas、MeiryoKe_Consoleを使用できるようになりましたが、IDEで指定できるフォントは通常1つだけです。そこでConsolasにフォントリンクを設定し、Consolasに存在しないコードポイントに対してMeiryoKe_Consoleを使用するようにします。
レジストリエディタで
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
を開き、新規作成で複数行文字列値を作成し、名前を"Consolas"として内容を
meiryoKeConsole.ttf
SimSun.TTC,SimSun
gulim.ttc,GulimChe
mingliu.ttc,MingLiU
(普通に使用するならmeiryoKeConsole.ttfだけで十分ですが)として再起動します。これでIDEで使用するフォントをConsolasに設定することでConsolas + MeiryoKe_Consoleの組み合わせになります。ただしWindows XPの場合はClearTypeを有効にし、さらに
Microsoft Typography - ClearType Tuner PowerToy
からClearType Tunerをダウンロード、インストールして好みの状態に調整したほうがいいでしょう。このあたりについては@ITの
Windows XPの正体 : 文字表示を滑らかにする新技術「ClearType」
ClearTypeフォントの表示方法を調整する - @IT
あたりが参考になります。
2011年4月19日
Webセミナー 次世代ToolCloud - AppWaveによるアプリケーション配布の管理
Webセミナー「次世代ToolCloud - AppWaveによるアプリケーション配布の管理」
始まりました。今日は資料ダウンロード、ビデオリプレイはありません。開発中のプロダクトについての話なので以下の内容はあくまで現時点のもので、一切の保証はありません、といういつものお約束で。詳細は今後ソフトウェア開発環境展(SODEC)(リード エグジビション ジャパン株式会社主催、2011/05/11-13、東京ビッグサイト)などで順次公開予定とのこと。
ユーザ、管理者、開発者のそれぞれの観点からみたAppWaveについて。
まずToolCloudとは、というおさらい。
配布、ライセンス管理の問題。webアプリケーション、thinクライアント、仮想化、クラウドといった方法での解決には一長一短がある。
AppWave技術で解決。クライアントサイドに仮想化環境を作りオンデマンド、ストリーミングで必要な実行モジュールを送り込む。
AppWaveブラウザを通してアプリケーションを配信して実行。プログラムからローカル資源にもアクセス可能。
ユーザの観点。評価時にも購入後もいちいちインストールしたりアンインストールしたりといった面倒な部分はAppWaveブラウザ内に閉じ込めることができ、ホストOS環境を汚染しない。AppWaveブラウザ内の状態はサーバ側に保存されるので別環境下でも同一アカウントであれば同一環境を得られる。
管理者の観点。ライセンスの一括/一元管理でもコーポレート/サイトライセンスでもライセンスの管理の維持が難しい。AppWaveではアプリケーションのユーザごとの使用の可否や使用状況を管理できる。AppWave StudioでアプリケーションをAppWave用にパッケージングする。パッケージング作業はアプリケーション固有のインストーラによる手順のキャプチャでも導入手順の手動設定でも可能。
開発者の観点。開発環境のインフラストラクチャとして。
導入イメージ。ツールやアプリケーションをAppWaveサーバから配信。部門ごとやプロジェクトごとの開発ツールの環境やライセンスを一元管理できる。市販アプリケーションのライセンス管理、最新バージョンの強制などもできる。パッケージアプリケーションの配布にも。購入済ユーザ、トライアルユーザなどライセンスの管理も簡単に。
AppWaveブラウザについて。現状はエンバカデロのツールのみ。次のステップでは管理者がAppWave Studioでパッケージングしたものを追加できるようになる。さらにAppWave Store(仮)でアプリケーションの配信、販売、という将来構想。AppWave Store(現在ベータテスト中)のメンバとなり、Storeにアプリケーション、ツール、コンポーネントなどを登録すればAppWave Store経由で販売が可能になる。
まとめ。AppWaveはToolCloudを汎用化したもので、将来はStore機能までつなげていきたい。
Q&A。オフライン実行については最長1ヶ月のライセンスの持ち出しができる。
終了。おつかれさまでした。
始まりました。今日は資料ダウンロード、ビデオリプレイはありません。開発中のプロダクトについての話なので以下の内容はあくまで現時点のもので、一切の保証はありません、といういつものお約束で。詳細は今後ソフトウェア開発環境展(SODEC)(リード エグジビション ジャパン株式会社主催、2011/05/11-13、東京ビッグサイト)などで順次公開予定とのこと。
ユーザ、管理者、開発者のそれぞれの観点からみたAppWaveについて。
まずToolCloudとは、というおさらい。
配布、ライセンス管理の問題。webアプリケーション、thinクライアント、仮想化、クラウドといった方法での解決には一長一短がある。
AppWave技術で解決。クライアントサイドに仮想化環境を作りオンデマンド、ストリーミングで必要な実行モジュールを送り込む。
AppWaveブラウザを通してアプリケーションを配信して実行。プログラムからローカル資源にもアクセス可能。
ユーザの観点。評価時にも購入後もいちいちインストールしたりアンインストールしたりといった面倒な部分はAppWaveブラウザ内に閉じ込めることができ、ホストOS環境を汚染しない。AppWaveブラウザ内の状態はサーバ側に保存されるので別環境下でも同一アカウントであれば同一環境を得られる。
管理者の観点。ライセンスの一括/一元管理でもコーポレート/サイトライセンスでもライセンスの管理の維持が難しい。AppWaveではアプリケーションのユーザごとの使用の可否や使用状況を管理できる。AppWave StudioでアプリケーションをAppWave用にパッケージングする。パッケージング作業はアプリケーション固有のインストーラによる手順のキャプチャでも導入手順の手動設定でも可能。
開発者の観点。開発環境のインフラストラクチャとして。
導入イメージ。ツールやアプリケーションをAppWaveサーバから配信。部門ごとやプロジェクトごとの開発ツールの環境やライセンスを一元管理できる。市販アプリケーションのライセンス管理、最新バージョンの強制などもできる。パッケージアプリケーションの配布にも。購入済ユーザ、トライアルユーザなどライセンスの管理も簡単に。
AppWaveブラウザについて。現状はエンバカデロのツールのみ。次のステップでは管理者がAppWave Studioでパッケージングしたものを追加できるようになる。さらにAppWave Store(仮)でアプリケーションの配信、販売、という将来構想。AppWave Store(現在ベータテスト中)のメンバとなり、Storeにアプリケーション、ツール、コンポーネントなどを登録すればAppWave Store経由で販売が可能になる。
まとめ。AppWaveはToolCloudを汎用化したもので、将来はStore機能までつなげていきたい。
Q&A。オフライン実行については最長1ヶ月のライセンスの持ち出しができる。
終了。おつかれさまでした。
IDE Fix Pack 4.0/DelphiSpeedUp 3.0リリース
Andreas HausladenさんのIDE Fix Pack 2007およびIDE Fix Pack 2009/2010/XEがアップデートされてVersion 4.0に、DelphiSpeedUpもDelphi 7/2007用がアップデートされてVersion 3.0になっています。
IDE Fix Pack 4.0 / DelphiSpeedUp 3.0 release | Andy’s Blog and Tools
IDE Fix Pack 4.0 / DelphiSpeedUp 3.0 release | Andy’s Blog and Tools
2011年4月18日
VMware Player上のWindwos XPモードでマルチコアを有効にする
Windows 7のProfessional/Ultimate/Enterprise SKUで使用できるWindows XP モードをVMware Playerにインポートして使用することができます。このときホスト側のCPUがマルチコアで、かつVMware Playerの設定でVMに複数のCPUコアを割り当てる設定にしてあっても、XPモードのHALがシングルプロセッサにのみ対応した状態のため、実際にはシングルコアでしか動作しません(Virtual PC上のXPモードがシングルプロセッサのみをサポートしているためと考えられます)。そこでHALを入れ替えることでマルチコアを有効にする方法を説明したページを見つけました。
VMware Player 3の XP Mode をマルチコアで動かす方法
要約:
このページの説明ではHALを入れ替えることなくVMのCPU割り当てを2以上にするとBSODになる、とされていますが、手元のAMD Phenom II X6環境では単純にシングルコア動作になるだけでした。
参考: VMware PlayerおよびXPモードに関する記事のリンク
Windows Server Insider 検証 - @IT
Windows XP Modeとディスク管理機能 - @IT
VMware Player 3の XP Mode をマルチコアで動かす方法
要約:
- %systemroot%\Driver Cache\i386\sp3.cabに格納されているhalaacpi.dllおよびhalmacpi.dllを%systemroot%\system32にコピー
- boot.iniの起動オプションにを追加してシャットダウン
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional (ACPI/APIC)" /noexecute=optin /fastdetect /hal=halaacpi.dll
- VMの設定でプロセッサコア数を2に変更
- VMを起動してオペレーティングシステムの選択で下の項目("Microsoft Windows XP Professional (ACPI/APIC)")を選択して起動
- ハードウェアの変更が自動的に検出されドライバのインストール後に再起動を求められるので再起動
- オペレーティングシステムの選択で今度は上の項目("Microsoft Windows XP Professional")を選択して起動
- タスクマネージャでCPUが2つになっていることを確認
- boot.iniの起動オプションに追加した"Microsoft Windows XP Professional (ACPI/APIC)"を削除
このページの説明ではHALを入れ替えることなくVMのCPU割り当てを2以上にするとBSODになる、とされていますが、手元のAMD Phenom II X6環境では単純にシングルコア動作になるだけでした。
参考: VMware PlayerおよびXPモードに関する記事のリンク
Windows Server Insider 検証 - @IT
Windows XP Modeとディスク管理機能 - @IT
2011年4月15日
DelphiでSingletonパターンを実装する(再考)
初回のアーティクルに
シングルトンに求められる条件を考えれば、インスタンスを破棄された後でアクセスされたときはインスタンスを再度生成する("Phoenix Singleton")か、外部からは破棄できないようにするか、いずれかが望ましいと考えられます。
まず再生成する場合です。こちらはインスタンスの破棄時にインスタンスへの参照を初期化することで、次回参照時にインスタンスを再度生成します。initialization/finalization版から。
こちらもinitialization/finalization版から。
シングルトンのインスタンスは外部から破棄可能だけどいいの?(意訳)というご意見を高橋さんから頂きました。確かにどの実装も、取得したインスタンスに対してFree(あるいはDestroy)を行うことで解放できてしまいます。
シングルトンに求められる条件を考えれば、インスタンスを破棄された後でアクセスされたときはインスタンスを再度生成する("Phoenix Singleton")か、外部からは破棄できないようにするか、いずれかが望ましいと考えられます。
まず再生成する場合です。こちらはインスタンスの破棄時にインスタンスへの参照を初期化することで、次回参照時にインスタンスを再度生成します。initialization/finalization版から。
unit Unit20;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
constructor CreateInstance;
public
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
var
FSingleton: TSingleton;
{ TSingleton }
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Delete singleton reference }
FSingleton := nil;
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
Result := FSingleton;
end;
initialization
FSingleton := nil;
finalization
FSingleton.Free;
end.
再生成する場合のclass constructor/class destructor版です。unit Unit22;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
class var
FSingleton: TSingleton;
constructor CreateInstance;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
{ TSingleton }
class constructor TSingleton.Create;
begin
FSingleton := nil;
end;
class destructor TSingleton.Destroy;
begin
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Delete singleton reference }
FSingleton := nil;
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
Result := FSingleton;
end;
end.
次に外部からの破棄を禁止する場合です。destructor Destroy (ja)もconstructor Create (ja)と同様にTObjectでpublicとされていてスコープを狭化できないため、例外を送出することでインスタンスの破棄をブロックしています(コンストラクタと違いドキュメントなどで明示されていませんが、逆アセンブル表示で見る限りデストラクタもまた例外の送出で処理をブロックできると考えます)。ただし通常のコンストラクタ呼び出しからデストラクタが呼ばれる場合と、終了時にデストラクタが呼ばれる場合はフラグで区別して通常の処理を行います。こちらもinitialization/finalization版から。
unit Unit24;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
constructor CreateInstance;
public
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
EDestroySingleton = class(Exception)
end;
implementation
var
FSingleton: TSingleton;
FInternalDestroy: Boolean;
{ TSingleton }
constructor TSingleton.Create;
begin
FInternalDestroy := True;
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
if FInternalDestroy = False then
begin
raise EDestroySingleton.Create('TSingleton.Destroy cannnot use.');
end;
FInternalDestroy := False;
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
Result := FSingleton;
end;
initialization
FSingleton := nil;
finalization
FInternalDestroy := True;
FSingleton.Free;
end.
最後に外部から破棄を禁止する場合のclass constructor/class destructor版です。unit Unit26;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
class var
FSingleton: TSingleton;
FInternalDestroy: Boolean;
constructor CreateInstance;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
EDestroySingleton = class(Exception)
end;
implementation
{ TSingleton }
class constructor TSingleton.Create;
begin
FSingleton := nil;
end;
class destructor TSingleton.Destroy;
begin
FInternalDestroy := True;
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
FInternalDestroy := True;
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
if FInternalDestroy = False then
begin
raise EDestroySingleton.Create('TSingleton.Destroy cannnot use.');
end;
FInternalDestroy := False;
{ Finalize }
inherited Destroy;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
Result := FSingleton;
end;
end.
2011年4月14日
DelphiでSingletonパターンを実装する(Monitor版)
前回の実装のなかで、CriticalSectionを使用して排他をかけるもの(Unit12)がありましたが、Delphi 2009の新機能のなかにMonitor (ja)という同期メカニズムがあります。そこでCriticalSectionのかわりにMonitorを使用したバージョンを作ってみました。
元ねたは
What is TMonitor in Delphi System unit good for? - Stack Overflow
Monitor (synchronization) - Wikipedia, the free encyclopedia (ja)
Craig Stuntz’s Weblog : Why Has the Size of TObject Doubled In Delphi 2009?
The Oracle at Delphi » Simmering Unicode, bring DPL to a boil
The Oracle at Delphi » Simmering Unicode, bring DPL to a boil (Part 2)
The Oracle at Delphi » Breaking the rules
あたり。System.TMonitorの詳しい説明とかサンプルはないんでしょうか?
2011/04/15追記: .NET FrameworkのMonitorクラスの説明が参考になりそうです。
Monitor クラス (System.Threading)
実装例は第15回 エンバカデロ・デベロッパーキャンプの【A5】Delphi/C++テクニカルセッション「詳説!DataSnap 2010」のコネクションプーリングの実装あたりでしょうか(高橋さん、いつも情報ありがとうございます)。
unit Unit18;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
class var
FSingleton: TSingleton;
FLock: TObject;
constructor CreateInstance;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
{ TSingleton }
class constructor TSingleton.Create;
begin
FSingleton := nil;
FLock := TObject.Create;
end;
class destructor TSingleton.Destroy;
begin
FLock.Free;
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
System.TMonitor.Enter(FLock);
try
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
finally
System.TMonitor.Exit(FLock);
end;
Result := FSingleton;
end;
end.
元ねたは
What is TMonitor in Delphi System unit good for? - Stack Overflow
Monitor (synchronization) - Wikipedia, the free encyclopedia (ja)
Craig Stuntz’s Weblog : Why Has the Size of TObject Doubled In Delphi 2009?
The Oracle at Delphi » Simmering Unicode, bring DPL to a boil
The Oracle at Delphi » Simmering Unicode, bring DPL to a boil (Part 2)
The Oracle at Delphi » Breaking the rules
あたり。System.TMonitorの詳しい説明とかサンプルはないんでしょうか?
2011/04/15追記: .NET FrameworkのMonitorクラスの説明が参考になりそうです。
Monitor クラス (System.Threading)
実装例は第15回 エンバカデロ・デベロッパーキャンプの【A5】Delphi/C++テクニカルセッション「詳説!DataSnap 2010」のコネクションプーリングの実装あたりでしょうか(高橋さん、いつも情報ありがとうございます)。
2011年4月13日
TMS IDE Rich Clip
以前、デベロッパーキャンプなどのプレゼンテーション資料を作ったりするときにDelphiのコードをMicrosoft WordやPowerPointにきれいに貼り付けるにはどうしたらいいか、という話がありましたが、TMS SoftwareがDelphi 2010/XE用に
TMS IDE Rich Clip
というIDEプラグインを無償で公開しているのを見つけました。IDE上でコードを選択した状態で編集メニューの"Copy as RTF"あるいは"Copy as HTML"を指定すると、コードがシンタックスハイライトされたRTF/HTML形式でクリップボードにコピーされます。
ただ試した範囲ではインストーラが正しくパッケージをIDEに組み込むことができず、一旦パッケージを削除してから改めて登録する必要がありました。IDE起動時にエラーになった場合はコンポーネント|パッケージでパッケージ一覧を表示し、当該パッケージを削除した後で再度追加してみてください。
元ねたはTMS Software | Blog | Color your Delphi source code on the clipboard。
TMS IDE Rich Clip
というIDEプラグインを無償で公開しているのを見つけました。IDE上でコードを選択した状態で編集メニューの"Copy as RTF"あるいは"Copy as HTML"を指定すると、コードがシンタックスハイライトされたRTF/HTML形式でクリップボードにコピーされます。
ただ試した範囲ではインストーラが正しくパッケージをIDEに組み込むことができず、一旦パッケージを削除してから改めて登録する必要がありました。IDE起動時にエラーになった場合はコンポーネント|パッケージでパッケージ一覧を表示し、当該パッケージを削除した後で再度追加してみてください。
元ねたはTMS Software | Blog | Color your Delphi source code on the clipboard。
Microsoft Monthly Update 2011/04
今日はMicrosoftのセキュリティアップデートの日です。
MS11-018
MS11-019
MS11-020
MS11-021
MS11-022
MS11-023
MS11-024
MS11-025
MS11-026
MS11-027
MS11-028
MS11-029
MS11-030
MS11-031
MS11-032
MS11-033
MS11-034
Windows 2000 SP4ではMS11-025のVisual C++ 2005 SP1 Redistributable Packageを適用するとMFC80*.DLLを使用するプログラムが起動しなくなるため、MBSAで警告されても無視しましょう(Windows XP以降でKernel32に追加された関数をスタティックにリンクしているため)。
2011/04/15追記: MS11-025の更新プログラムはWindows 2000あるいはWindos 2000をターゲットに開発する環境には適用するべきではないようです。
Security Update KB2467174 kills Windows 2000 compatibility of mfc90.dll
New redists break all dynamically linked MFC 2005/2008 apps on Windows 2000 « Ted's Blog
自動更新あるいはMBSAの警告に従ってWindows 2000にMS11-025のRedistributable Packageの更新プログラムを適用してしまい、FindActCtxSectionStringAが欠陥エクスポートとなってプログラムが起動できなくなった場合は、更新プログラムを削除→MFC80*.DLL/MFC90*.DLLを削除→古いRedistributable Packageをダウンロードしてインストール、という手順でとりあえず回復することができます(最終的にどのような解決が図られるのかは不明ですが)。
ダウンロードの詳細 : Visual C++ 2005 SP1 再頒布可能パッケージ (x86)
ダウンロードの詳細 : Visual C++ 2008 SP1 再頒布可能パッケージ (x86)
Visual Studioについても同様で、MS11-025の更新プログラムを適用してMFCアプリケーションをリビルドするとWindows 2000では動作しないバイナリが生成されます。
2011/05/02追記: MS11-025の問題についてはこちらのアーティクルを参照してください。
MS11-018
MS11-019
MS11-020
MS11-021
MS11-022
MS11-023
MS11-024
MS11-025
MS11-026
MS11-027
MS11-028
MS11-029
MS11-030
MS11-031
MS11-032
MS11-033
MS11-034
Windows 2000 SP4ではMS11-025のVisual C++ 2005 SP1 Redistributable Packageを適用するとMFC80*.DLLを使用するプログラムが起動しなくなるため、MBSAで警告されても無視しましょう(Windows XP以降でKernel32に追加された関数をスタティックにリンクしているため)。
2011/04/15追記: MS11-025の更新プログラムはWindows 2000あるいはWindos 2000をターゲットに開発する環境には適用するべきではないようです。
Security Update KB2467174 kills Windows 2000 compatibility of mfc90.dll
New redists break all dynamically linked MFC 2005/2008 apps on Windows 2000 « Ted's Blog
自動更新あるいはMBSAの警告に従ってWindows 2000にMS11-025のRedistributable Packageの更新プログラムを適用してしまい、FindActCtxSectionStringAが欠陥エクスポートとなってプログラムが起動できなくなった場合は、更新プログラムを削除→MFC80*.DLL/MFC90*.DLLを削除→古いRedistributable Packageをダウンロードしてインストール、という手順でとりあえず回復することができます(最終的にどのような解決が図られるのかは不明ですが)。
ダウンロードの詳細 : Visual C++ 2005 SP1 再頒布可能パッケージ (x86)
ダウンロードの詳細 : Visual C++ 2008 SP1 再頒布可能パッケージ (x86)
Visual Studioについても同様で、MS11-025の更新プログラムを適用してMFCアプリケーションをリビルドするとWindows 2000では動作しないバイナリが生成されます。
2011/05/02追記: MS11-025の問題についてはこちらのアーティクルを参照してください。
2011年4月12日
DelphiでSingletonパターンを実装する(続き)
前回の実装では基本的にinitialization (ja)/finalization (ja)部でインスタンス変数を処理していましたが、この方法だと(T)Singletonを実際には使用していなくてもDelphiのリンカがそれを認識できず、TSingletonのコードを常にリンク対象としてしまう、という問題点があります(それ以上にあんまりオブジェクト指向っぽくない、という点も…)。そこでinitialization/finalization部の処理をDelphi 2010で導入されたクラスコンストラクタ (ja)/クラスデストラクタ (ja)で置き換えて、必要ないコードのリンクが行われないようにしてみます。
まず"シングルトンもどき"です。
まず"シングルトンもどき"です。
unit Unit4;
interface
type
TSingleton = class(TObject)
private
FTestValue: Integer;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
function Singleton: TSingleton;
implementation
var
FSingleton: TSingleton;
function Singleton: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.Create;
end;
Result := FSingleton;
end;
class constructor TSingleton.Create;
begin
FSingleton := nil;
end;
class destructor TSingleton.Destroy;
begin
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
inherited;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
end.
次に"本当の"シングルトンです。unit Unit8;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
class var
FSingleton: TSingleton;
constructor CreateInstance;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
{ TSingleton }
class constructor TSingleton.Create;
begin
FSingleton := nil;
end;
class destructor TSingleton.Destroy;
begin
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
Result := FSingleton;
end;
end.
CriticalSectionによる排他処理を加えたものです。unit Unit12;
interface
uses
SysUtils, Windows;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
class var
FSingleton: TSingleton;
FCriticalSection: TRTLCriticalSection;
constructor CreateInstance;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
{ TSingleton }
type
TInitializeCriticalSectionExFunc = function(var lpCriticalSection: TRTLCriticalSection;
dwSpinCount: DWORD;
Flags: DWORD): BOOL; stdcall;
const
CRITICAL_SECTION_NO_DEBUG_INFO = $01000000;
class constructor TSingleton.Create;
var
InitializeCriticalSectionEx: TInitializeCriticalSectionExFunc;
begin
FSingleton := nil;
@InitializeCriticalSectionEx := GetProcAddress(GetModuleHandle(kernel32),
'InitializeCriticalSectionEx');
if Assigned(InitializeCriticalSectionEx) = True then
begin
InitializeCriticalSectionEx(FCriticalSection,0,CRITICAL_SECTION_NO_DEBUG_INFO);
end
else
begin
InitializeCriticalSectionAndSpinCount(FCriticalSection,0);
end;
end;
class destructor TSingleton.Destroy;
begin
DeleteCriticalSection(FCriticalSection);
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
EnterCriticalSection(FCriticalSection);
try
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
finally
LeaveCriticalSection(FCriticalSection);
end;
Result := FSingleton;
end;
end.
最後に事前初期化版です。unit Unit16;
interface
uses
SysUtils, Windows;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
class var
FSingleton: TSingleton;
constructor CreateInstance;
public
class constructor Create;
class destructor Destroy;
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
{ TSingleton }
class constructor TSingleton.Create;
begin
FSingleton := TSingleton.CreateInstance;
end;
class destructor TSingleton.Destroy;
begin
FSingleton.Free;
end;
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
Result := FSingleton;
end;
end.
プロジェクト内でTSingletonを使用していない場合、TSingleton関係のコードがリンクされないことがわかります。
TMS Smooth Controls for Delphi and C++Builder XE
まだ正式なアナウンスはありませんが、RADStudio/Delphi/C++Builder XEの登録ユーザ向にTMS SoftwareのTMS Smooth Controls for Delphi and C++Builder XEがCodeCentralからダウンロードできるようになっています。
28271 TMS Smooth Controls for Delphi and C++Builder XE
どうやらUSで始まったGet RAD Studio XE at the Delphi/C++Builder Price!というキャンペーンの一環で
2011/06/01追記: 登録ユーザダウンロードに表示されているのでいまさらのような気がしますが、日本でもキャンペーンが始まったようです。
Team Japan » 「TMS Smooth Controls Pack for Delphi XE and C++Builder XE」を入手しよう
強力なビジュアル開発ツールスイート「RAD Studio XE」にアップグレードしよう!
28271 TMS Smooth Controls for Delphi and C++Builder XE
どうやらUSで始まったGet RAD Studio XE at the Delphi/C++Builder Price!というキャンペーンの一環で
Plus bonus TMS Smooth Controls Pack at no extra chargeということのようです。日本ではどうなるのでしょうか。高橋さん、情報ありがとうございます。
2011/06/01追記: 登録ユーザダウンロードに表示されているのでいまさらのような気がしますが、日本でもキャンペーンが始まったようです。
Team Japan » 「TMS Smooth Controls Pack for Delphi XE and C++Builder XE」を入手しよう
強力なビジュアル開発ツールスイート「RAD Studio XE」にアップグレードしよう!
2011年4月11日
DelphiでSingletonパターンを実装する
GoFによるデザインパターンのシングルトンパターンをDelphiで実装することを考えてみます。シングルトンパターン(Singleton pattern)とは、
最初に"シングルトンもどき"です。Delphiプログラマがシングルトンと聞くと、Printerオブジェクト(Printers.Printer (ja))を思い浮かべることが多いのではないでしょうか。Printerは厳密な意味でのシングルトンではありませんが、実用上はこの程度の実装で十分なことが多いのも確かです。この"シングルトンもどき"("Printerパターン"?)は、唯一となるべきインスタンスを格納する変数を隠蔽して、代わりにインスタンスを返す関数を用意しておき、最初のアクセスでインスタンスを生成する、というやりかたで、実際には複数のインスタンスを生成することが可能なのですが、逆にグローバルなインスタンスは一つでも、ローカル/一時的なインスタンスはそれとは別に生成したい、というような場合にはとても適合しています。
次に"本当の"シングルトンを考えてみます。ただしDelphiでは、全てのクラスがpublicなconstructor Create (ja)を持つTObject (ja)から派生しており、かつメンバ関数のスコープを狭めることができないという言語仕様から、C++やJavaのように通常のコンストラクタ呼び出しをコンパイルエラーにすることができません。そこで次善の策としてpublicなコンストラクタを呼び出すと例外がraiseされ、インスタンスの生成に失敗するようにしてみました。
しかしよく指摘されるように、これらの実装には、マルチスレッドになっているプログラム上で別々のスレッドから競合するタイミングでTSingleton.GetInstanceを呼び出すとインスタンスが多重に生成される可能性がある、という問題が存在しています。これを避けるためにCriticalSectionで排他をかけてみます。なおWindows Vista以降ではクリティカルセクション構造体をInitializeCriticalSectionで初期化するとリソースリークし、一方でWindows 2000ではInitializeCriticalSectionで初期化すると残りメモリが逼迫したときにEnterCriticalSectionで例外が発生するという問題があるので、可能であればInitializeCriticalSectionExを、それ以外ではInitializeCriticalSectionAndSpinCount (ja)を呼び出すようにしています。
排他処理のコストを無視することができない場合は、通常のシングルトンパターンの実装の長所の一つである"インスタンスの生成を必要になるまで遅延する"を捨てて、インスタンスをアプリケーションの初期化時に生成してしまう、という方法もあります。
元ねたはオブジェクト指向における再利用のためのデザインパターン(改訂版) (amazon) (Erich Gamma、Richard Helm、Ralph Johnson、John M. Vlissides著/本位田 真一、吉田 和樹監訳/ソフトバンククリエイティブ/ISBN4-7973-1112-6(ISBN978-4797311129)/5,040円)とHead Firstデザインパターン (amazon) (Eric Freeman、Elisabeth Freeman、Kathy Sierra、Bert Bates著/木下 哲也、有限会社 福龍興業訳/佐藤 直生監訳/ISBN4-87311-249-4/4,830円)。
あるクラスに対してインスタンスが1つしか存在しないことを保証し、それにアクセスするためのグローバルな方法を提供する。ことを目的とした"生成に関するパターン"の一つです。
最初に"シングルトンもどき"です。Delphiプログラマがシングルトンと聞くと、Printerオブジェクト(Printers.Printer (ja))を思い浮かべることが多いのではないでしょうか。Printerは厳密な意味でのシングルトンではありませんが、実用上はこの程度の実装で十分なことが多いのも確かです。この"シングルトンもどき"("Printerパターン"?)は、唯一となるべきインスタンスを格納する変数を隠蔽して、代わりにインスタンスを返す関数を用意しておき、最初のアクセスでインスタンスを生成する、というやりかたで、実際には複数のインスタンスを生成することが可能なのですが、逆にグローバルなインスタンスは一つでも、ローカル/一時的なインスタンスはそれとは別に生成したい、というような場合にはとても適合しています。
unit Unit2;
interface
type
TSingleton = class(TObject)
private
FTestValue: Integer;
public
constructor Create;
destructor Destroy; override;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
function Singleton: TSingleton;
implementation
var
FSingleton: TSingleton;
function Singleton: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.Create;
end;
Result := FSingleton;
end;
constructor TSingleton.Create;
begin
inherited;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
initialization
FSingleton := nil;
finalization
FSingleton.Free;
end.
Singleton関数を通してグローバルな唯一のインスタンスを取得することができ、必要に応じてコンストラクタを呼び出すことでローカル/一時的なインスタンスを生成することもできます。次に"本当の"シングルトンを考えてみます。ただしDelphiでは、全てのクラスがpublicなconstructor Create (ja)を持つTObject (ja)から派生しており、かつメンバ関数のスコープを狭めることができないという言語仕様から、C++やJavaのように通常のコンストラクタ呼び出しをコンパイルエラーにすることができません。そこで次善の策としてpublicなコンストラクタを呼び出すと例外がraiseされ、インスタンスの生成に失敗するようにしてみました。
unit Unit6;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
constructor CreateInstance;
public
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
var
FSingleton: TSingleton;
{ TSingleton }
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
Result := FSingleton;
end;
initialization
FSingleton := nil;
finalization
FSingleton.Free;
end.
TSingleton.GetInstanceを呼び出すことでTSingletonの唯一のインスタンスにアクセスすることができます。しかしよく指摘されるように、これらの実装には、マルチスレッドになっているプログラム上で別々のスレッドから競合するタイミングでTSingleton.GetInstanceを呼び出すとインスタンスが多重に生成される可能性がある、という問題が存在しています。これを避けるためにCriticalSectionで排他をかけてみます。なおWindows Vista以降ではクリティカルセクション構造体をInitializeCriticalSectionで初期化するとリソースリークし、一方でWindows 2000ではInitializeCriticalSectionで初期化すると残りメモリが逼迫したときにEnterCriticalSectionで例外が発生するという問題があるので、可能であればInitializeCriticalSectionExを、それ以外ではInitializeCriticalSectionAndSpinCount (ja)を呼び出すようにしています。
unit Unit10;
interface
uses
SysUtils, Windows;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
constructor CreateInstance;
public
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
var
FSingleton: TSingleton;
FCriticalSection: TRTLCriticalSection;
{ TSingleton }
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
EnterCriticalSection(FCriticalSection);
try
if FSingleton = nil then
begin
FSingleton := TSingleton.CreateInstance;
end;
finally
LeaveCriticalSection(FCriticalSection);
end;
Result := FSingleton;
end;
type
TInitializeCriticalSectionExFunc = function(var lpCriticalSection: TRTLCriticalSection;
dwSpinCount: DWORD;
Flags: DWORD): BOOL; stdcall;
const
CRITICAL_SECTION_NO_DEBUG_INFO = $01000000;
procedure InitializeSingleton;
var
InitializeCriticalSectionEx: TInitializeCriticalSectionExFunc;
begin
FSingleton := nil;
@InitializeCriticalSectionEx := GetProcAddress(GetModuleHandle(kernel32),
'InitializeCriticalSectionEx');
if Assigned(InitializeCriticalSectionEx) = True then
begin
InitializeCriticalSectionEx(FCriticalSection,0,CRITICAL_SECTION_NO_DEBUG_INFO);
end
else
begin
InitializeCriticalSectionAndSpinCount(FCriticalSection,0);
end;
end;
initialization
InitializeSingleton;
finalization
DeleteCriticalSection(FCriticalSection);
FSingleton.Free;
end.
上記の例と同様にTSingleton.GetInstanceでTSingletonの唯一のインスタンスにアクセスすることができますが、GetInstanceを呼び出す毎にEnterCriticalSection/LeaveCriticalSectionするため、一旦インスタンスが生成された後でも本質的に必要のないオーバヘッドが存在しています。排他処理のコストを無視することができない場合は、通常のシングルトンパターンの実装の長所の一つである"インスタンスの生成を必要になるまで遅延する"を捨てて、インスタンスをアプリケーションの初期化時に生成してしまう、という方法もあります。
unit Unit14;
interface
uses
SysUtils;
type
TSingleton = class(TObject)
private
FTestValue: Integer;
constructor CreateInstance;
public
constructor Create;
destructor Destroy; override;
class function GetInstance: TSingleton;
property TestValue: Integer
read FTestValue
write FTestValue;
end;
ECreateSingleton = class(Exception)
end;
implementation
var
FSingleton: TSingleton;
{ TSingleton }
constructor TSingleton.Create;
begin
raise ECreateSingleton.Create('TSingleton.Create cannot use.');
end;
constructor TSingleton.CreateInstance;
begin
inherited Create;
{ Initialize }
FTestValue := 0;
end;
destructor TSingleton.Destroy;
begin
{ Finalize }
inherited;
end;
class function TSingleton.GetInstance: TSingleton;
begin
Result := FSingleton;
end;
initialization
FSingleton := TSingleton.CreateInstance;
finalization
FSingleton.Free;
end.
現実のアプリケーションでは常にトレードオフが存在しますので、必要に応じてこれらのいずれかの(あるいはこれ以外でも)実装を選択する、ということになります。なお"これらのシングルトンに必要な実装を行った基底クラス"と"実際に使用するシングルトンの派生クラス"、というアプローチは(個人的には)いろんな意味で望ましいとは思えません。元ねたはオブジェクト指向における再利用のためのデザインパターン(改訂版) (amazon) (Erich Gamma、Richard Helm、Ralph Johnson、John M. Vlissides著/本位田 真一、吉田 和樹監訳/ソフトバンククリエイティブ/ISBN4-7973-1112-6(ISBN978-4797311129)/5,040円)とHead Firstデザインパターン (amazon) (Eric Freeman、Elisabeth Freeman、Kathy Sierra、Bert Bates著/木下 哲也、有限会社 福龍興業訳/佐藤 直生監訳/ISBN4-87311-249-4/4,830円)。
2011年4月9日
Delphi Prism XE Update 1
Delphi Prism XE Update 1がリリースされています。
28280 Delphi Prism XE ISO (Update 1)
28286 Delphi Prism XE Full Installer (Update 1) Japanese
Delphi Prism XE Update 1 now available
Delphi Prism XE Update 1 が公開されました
Fix list for Delphi Prism XE Update 1
Delphi Prism XE Update 1に関する修正リスト
どうやらUpdate 1はフルインストーラのみのようですね。
28280 Delphi Prism XE ISO (Update 1)
28286 Delphi Prism XE Full Installer (Update 1) Japanese
Delphi Prism XE Update 1 now available
Delphi Prism XE Update 1 が公開されました
Fix list for Delphi Prism XE Update 1
Delphi Prism XE Update 1に関する修正リスト
どうやらUpdate 1はフルインストーラのみのようですね。
2011年4月8日
[書籍]Delphi in Depth: ClientDataSets
CreateSpaceで注文した
Delphi in Depth: ClientDataSets (CreateSpace, amazon US)/Cary Jensen著/CreateSpace/ISBN 978-1461008583/44.99USD
が配送されてきました(2011/04/01に注文、Shippingの7.38USDを加えて52.37USD=4,537JPY(暫定値)4,450JPY(1USD=84.973JPY))。
元ねたはCary Jensen "Let's Get Technical": Delphi in Depth: ClientDataSets。
2011/04/14追記: 日本のAmazonでも扱いが始まったようです。4,795円ですので、CreateSpaceで買うのとあまり変わりませんね。
Amazon.co.jp: Delphi in Depth: Clientdatasets: Cary, Ph.d. Jensen: 洋書
元ねたはOldTPFunさんのtweet。
2011/04/28追記: カードの利用明細によると4,450円で決済された模様(円高ですね)。と、確認してみたらamazon.co.jpでの扱いが止まっているようです。Shippingを加えてもCreateSpaceで買ったほうがいいようですね。
Delphi in Depth: ClientDataSets (CreateSpace, amazon US)/Cary Jensen著/CreateSpace/ISBN 978-1461008583/44.99USD
が配送されてきました(2011/04/01に注文、Shippingの7.38USDを加えて52.37USD=
元ねたはCary Jensen "Let's Get Technical": Delphi in Depth: ClientDataSets。
2011/04/14追記: 日本のAmazonでも扱いが始まったようです。4,795円ですので、CreateSpaceで買うのとあまり変わりませんね。
Amazon.co.jp: Delphi in Depth: Clientdatasets: Cary, Ph.d. Jensen: 洋書
元ねたはOldTPFunさんのtweet。
2011/04/28追記: カードの利用明細によると4,450円で決済された模様(円高ですね)。と、確認してみたらamazon.co.jpでの扱いが止まっているようです。Shippingを加えてもCreateSpaceで買ったほうがいいようですね。
2011年4月5日
Delphi 64bitコンパイラスニークプレビュー
64bitコンパイラのスニークプレビューとベータプログラムがアナウンスされています。
Delphi 64-bit コンパイラ・スニークプレビュー (EDN/ja)
Delphi 64-bit Compiler Sneak Preview (日本語情報、プレビュービデオに日本語字幕付き)
Delphi 64-bit Compiler Sneak Preview (EDN/en)
Delphi 64-bit Compiler Sneak Preview
Delphi Insider: Delphi 64-bit Compiler Sneak Preview and Beta - Official Announcement
Delphi 64-bit Compiler Preview and Beta Program | Andreano Lanusse Blog | Technology and Software Development
スニークプレビューは先日のデベロッパーキャンプのT1セッションのものとほぼ同一(素材はおそらく前日の韓国向けのもの)でした。ベータプログラムはRAD Studio/Delphi XEユーザを優先、という話は64-bit版Delphiフィールドテストのご案内にもあるとおりです。
プレビュービデオを見ていて、呼出規約が原則として単一になる、というところで、safecall (ja)は依然として特別扱いになる(
Delphi 64-bit コンパイラ・スニークプレビュー (EDN/ja)
Delphi 64-bit Compiler Sneak Preview (日本語情報、プレビュービデオに日本語字幕付き)
Delphi 64-bit Compiler Sneak Preview (EDN/en)
Delphi 64-bit Compiler Sneak Preview
Delphi Insider: Delphi 64-bit Compiler Sneak Preview and Beta - Official Announcement
Delphi 64-bit Compiler Preview and Beta Program | Andreano Lanusse Blog | Technology and Software Development
スニークプレビューは先日のデベロッパーキャンプのT1セッションのものとほぼ同一(素材はおそらく前日の韓国向けのもの)でした。ベータプログラムはRAD Studio/Delphi XEユーザを優先、という話は64-bit版Delphiフィールドテストのご案内にもあるとおりです。
プレビュービデオを見ていて、呼出規約が原則として単一になる、というところで、safecall (ja)は依然として特別扱いになる(
safecall is still "special")、という一文があることに気付きました。safecallとはヘルプに
safecall 規約は、例外 'firewalls' を実装しています。 Win32 では、これがプロセス間の COM エラー通知を実装しています。とあるようにCOMインタフェースにおける例外保護を追加したものになります(Wikipediaにも解説がありますね)。
RAD Studio/Delphi/C++Builder XE付属のFinalBuilderのアップデート
RAD Studio/Delphi/C++Builder XEにバンドルされているFinalBuilderがアップデートされ、FinalBuilder Embarcadero Edition(Ent/Arc SKUのみ)が7.0.0.1105になっています。
FinalBuilder Update for RAD Studio XE, Delphi XE and C++Builder XE
RAD Studio XE, Delphi XE, C++Builder XE向け FinalBuilder アップデート
28278 FinalBuilder for Delphi, C++Builder and RAD Studio XE
FinalBuilder 7 Version History
FinalBuilder Update for RAD Studio XE, Delphi XE and C++Builder XE
RAD Studio XE, Delphi XE, C++Builder XE向け FinalBuilder アップデート
28278 FinalBuilder for Delphi, C++Builder and RAD Studio XE
FinalBuilder 7 Version History
2011年4月1日
Pulsarフィールドテスト
先日のデベロッパーキャンプのときにも話に出ていた次期版Delphi(Pulsar)のフィールドテスタ募集のお知らせです。
64-bit版Delphiフィールドテストのご案内
今回は「品質向上のためのフィードバックを目的としたフィールドテスト」(今回募集)と「新バージョンに向けての動作検証や開発準備を目的としたフィールドテスト」(後日募集予定)に(時期や目的を)分けて行うようです。64bit版Delphiが欲しくて仕方がなかった人は積極的に参加してみてはいかがでしょう。
64-bit版Delphiフィールドテストのご案内
今回は「品質向上のためのフィードバックを目的としたフィールドテスト」(今回募集)と「新バージョンに向けての動作検証や開発準備を目的としたフィールドテスト」(後日募集予定)に(時期や目的を)分けて行うようです。64bit版Delphiが欲しくて仕方がなかった人は積極的に参加してみてはいかがでしょう。
2011/04開催のウェブセミナー
2011/04/14 15:00-16:00(JST) 次世代ToolCloud - AppWaveによるアプリケーション配布の管理
2011/04/19 17:00-18:00(JST) 次世代ToolCloud - AppWaveによるアプリケーション配布の管理
2011/04/21 17:00-18:00(JST) データベース開発者のためのDB PowerStudio入門
2011/04/27 17:00-18:00(JST) DB PowerStudioで実現するデータベース管理の効率化
2011/04/19 17:00-18:00(JST) 次世代ToolCloud - AppWaveによるアプリケーション配布の管理
2011/04/21 17:00-18:00(JST) データベース開発者のためのDB PowerStudio入門
2011/04/27 17:00-18:00(JST) DB PowerStudioで実現するデータベース管理の効率化
登録:
投稿 (Atom)