2011年9月22日

Delphi XE2で生成される実行ファイルのバージョン情報についての問題とその解決策

というわけで、Delphi XE2では実行ファイルにバージョン情報がうまく設定されない、という問題があるようです。

Embarcadero Discussion Forums: XE2で、バージョンリソースの作成に問題があるようです
バージョン情報の問題 - au2010の日記

そこでまずVCLフォームアプリケーションを作成し、プロジェクトオプションのバージョン情報でターゲットを"すべての構成 - すべてのプラットフォーム"を選択しておいて、バージョン情報を設定します。これでプログラムをビルドしてProject1.exeのバージョン情報を見てみます。…ファイルバージョンが1.0.0.0、言語が英語(米国)(0x0409)、製品バージョンが1.0.0.0となり、これ以外の情報は反映されていません。どういうことでしょう?そこでProject1.dprojの内容を見てみます。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{AAD95BEF-E352-48D7-8BA1-FBC01F8BEC0D}</ProjectGuid>
<ProjectVersion>13.4</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>Project1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;dsnap;IndyCore;fmxase;inet;fmxobj;inetdbxpress;fmxdae;dbexpress;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_Build>4</VerInfo_Build>
<Manifest_File>None</Manifest_File>
<VerInfo_Keys>CompanyName=Owl's Perspective;FileDescription=プログラムの説明;FileVersion=1.2.3.4;InternalName=Project1.exe;LegalCopyright=;LegalTrademarks=Copyright 2011 Owl's Perspective. All rights reserved.;OriginalFilename=Project1.exe;ProductName=Project1;ProductVersion=2.3;Comments=コメント</VerInfo_Keys>
<Icon_MainIcon>c:\program files\embarcadero\rad studio\9.0\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_MinorVer>2</VerInfo_MinorVer>
<VerInfo_Release>3</VerInfo_Release>
<VerInfo_Locale>1041</VerInfo_Locale>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>AppBar230;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;vclie;vcltouch;websnap;VclSmp;vcl;dsnapcon;vclx;webdsnap;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>vcldbx;frx16;TeeDB;vclib;inetdbbde;Tee;AppBar230;svnui;ibxpress;vclimg;TtsAudgr230;frxDB16;intrawebdb_120_160;fmi;fs16;vclactnband;FMXTee;TeeUI;vcldb;bindcompvcl;vcldsnap;vclie;vcltouch;Intraweb_120_160;websnap;vclribbon;frxe16;VclSmp;fsDB16;vcl;CloudService;CodeSiteExpressPkg;FmxTeeUI;dsnapcon;vclx;webdsnap;svn;bdertl;adortl;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>false</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Unit1.pas">
<Form>Form1</Form>
<FormType>dfm</FormType>
</DCCReference>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1041</VersionInfo>
<VersionInfo Name="CodePage">932</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Project1.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k160.bpl">Microsoft Office 2000 オートメーション サーバー ラッパー コンポーネントのサンプル</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp160.bpl">Microsoft Office XP オートメーション サーバー ラッパー コンポーネントのサンプル</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment/>
<Platforms>
<Platform value="Win64">False</Platform>
<Platform value="Win32">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
</Project>

これをよく見ると気になる点が2つあります。
  1. ターゲット"すべての構成 - すべてのプラットフォーム"に相当する<PropertyGroup Condition="'$(Base)'!=''">の部分にバージョン情報であるVerInfo_KeyとVerInfo_Localeがあるのに、個別のターゲットに相当する<PropertyGroup Condition="'$(Base_Win32)'!=''">などにも設定した覚えのないバージョン情報が入っている。
  2. Delphi XEまで使用していた<Delphi.Personality>の<VersionInfo>、<VersionInfoKeys>が無視されている。
個別のターゲットの部分に設定していない情報が入っていることに関しては、プロジェクトオプションダイアログのバージョン情報ページでターゲットを変更すると表示されるものや実際に生成される実行ファイルのバージョン情報と一致していますね。ということで個別のターゲットの部分に入っているVerInfo_KeyとVerInfo_Localeを削除します(プロジェクトを閉じた状態でProject1.dprojを書き換えます)。


<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{AAD95BEF-E352-48D7-8BA1-FBC01F8BEC0D}</ProjectGuid>
<ProjectVersion>13.4</ProjectVersion>
<FrameworkType>VCL</FrameworkType>
<MainSource>Project1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;dsnap;IndyCore;fmxase;inet;fmxobj;inetdbxpress;fmxdae;dbexpress;$(DCC_UsePackage)</DCC_UsePackage>
<VerInfo_Build>4</VerInfo_Build>
<Manifest_File>None</Manifest_File>
<VerInfo_Keys>CompanyName=Owl's Perspective;FileDescription=プログラムの説明;FileVersion=1.2.3.4;InternalName=Project1.exe;LegalCopyright=;LegalTrademarks=Copyright 2011 Owl's Perspective. All rights reserved.;OriginalFilename=Project1.exe;ProductName=Project1;ProductVersion=2.3;Comments=コメント</VerInfo_Keys>
<Icon_MainIcon>c:\program files\embarcadero\rad studio\9.0\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_MinorVer>2</VerInfo_MinorVer>
<VerInfo_Release>3</VerInfo_Release>
<VerInfo_Locale>1041</VerInfo_Locale>
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<DCC_S>false</DCC_S>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_UsePackage>AppBar230;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;vclie;vcltouch;websnap;VclSmp;vcl;dsnapcon;vclx;webdsnap;$(DCC_UsePackage)</DCC_UsePackage>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_UsePackage>vcldbx;frx16;TeeDB;vclib;inetdbbde;Tee;AppBar230;svnui;ibxpress;vclimg;TtsAudgr230;frxDB16;intrawebdb_120_160;fmi;fs16;vclactnband;FMXTee;TeeUI;vcldb;bindcompvcl;vcldsnap;vclie;vcltouch;Intraweb_120_160;websnap;vclribbon;frxe16;VclSmp;fsDB16;vcl;CloudService;CodeSiteExpressPkg;FmxTeeUI;dsnapcon;vclx;webdsnap;svn;bdertl;adortl;$(DCC_UsePackage)</DCC_UsePackage>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<DCC_RemoteDebug>false</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>false</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Unit1.pas">
<Form>Form1</Form>
<FormType>dfm</FormType>
</DCCReference>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1041</VersionInfo>
<VersionInfo Name="CodePage">932</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Project1.dpr</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k160.bpl">Microsoft Office 2000 オートメーション サーバー ラッパー コンポーネントのサンプル</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp160.bpl">Microsoft Office XP オートメーション サーバー ラッパー コンポーネントのサンプル</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Deployment/>
<Platforms>
<Platform value="Win64">False</Platform>
<Platform value="Win32">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
</Project>

これでプロジェクトを開きなおしてコンパイルしてみましょう。今度は設定したバージョン情報が正しく格納されていますね。ということでこの問題はXE2でバージョン情報の設定をターゲット毎に設定できるように仕様を変更したことによる不具合だと考えられます。また直接dprojファイルの不要な部分を削除することで回避できる、ということになります。

参考: DEKOさんのところの11/09/22 バージョン情報の件 (XE2) 11/09/22 バージョン情報の件 (XE2)。構成毎の設定が必要な場合について解説されています。

2011年9月21日

Delphi/C++Builder XE2におけるパッケージ作成時の注意点

Delphi/C++Builder XE2でパッケージを作るときに注意すると幸せになれるかもしれないけれどもあんまり参考にならないポイントを3つほど。
  • 出力ディレクトリ
    "プロジェクトオプション"の"Delphiコンパイラ"ページで"ユニットの出力ディレクトリ"を変更してもコンパイル時にデフォルトの出力ディレクトリ([WIN32][WIN64]\[DEBUG][RELEASE])が作成されてしまいます。これは.dprojファイル(xml形式)のDCC_ExeOutputにデフォルトのDCC_DcuOutputの内容が残っているためで、これをDCC_DcuOutputと同じ内容に書き換えることで回避することができます。
  • デザインパッケージ
    設計時パッケージでコンポーネントのプロパティエディタなどを作成した場合、デザインパッケージ"DesignIDE"が必要になりますが、単純にRequiresに追加してしまうとx64にはDesignIDEが存在しないためにx64版のコンパイルでエラーになってしまいます。この場合は"プロジェクトオプション"のターゲットで"すべての構成 - 32ビット Windows プラットフォーム"を選択し、"Delphiコンパイラ"の"コンパイル"ページの"コンパイラに渡す追加オプション"に"-LUDesignIDE"を追加することで回避することができます。
  • バージョン情報
    プロジェクトオプションでバージョン情報を追加してもターゲット構成(WIN32/WIN64/OS X/Debug/Release)毎にデフォルトの指定が残ってしまい、パッケージに正しいバージョン情報をつけることができません(もちろん全てのプロファイルに同じ内容を設定すればよいのですが)。これは.dprojファイルの構成毎の設定のところに不適切なVerInfo_LocaleとVerInfo_Keysの値が入ってしまっているためで、ベース構成以外のVerInfo_LocaleとVerInfo_Keysの要素を削除することで回避することができます。

ちなみに.dprojファイルのバージョン情報に関する設定の格納方法がXE2で変更になったようで、従来は"\Project\ProjectExtensions\BorlandProject\Delphi.Personality"のVersionInfoとVersionInfoKeysにバージョン情報の設定が存在しますが、XE2ではこの位置にある設定を無視して"\Project\PropertyGroup"のベース構成(CONDITION="'$(Base)'!=''")のVerInfo_*を使用するようです。XE2でバージョン情報関係の不具合が報告されているようですが、これらの仕様変更と関係があるような気がします(次回に続く)。

InterBase XE Update 3リリース

InterBase XE Update 3がリリースされています。バージョンは10.0.3.566となっています。

InterBase XE Update 3 Readme (日本語)
InterBase XE Update 3 Readme
Team Japan » InterBase XE Update 3 (10.0.3.566) の日本語版
InterBase XE Update 3 での IBCosole の機能強化
IBConsole enhancements in InterBase XE Update 3

28531 InterBase XE 32-bit Update 3 (10.0.3.566) for Windows, Japanese
28490 InterBase XE 32-bit Update 3 (10.0.3.566) for Windows, English
28532 InterBase XE 64-bit Update 3 (10.0.3.566) for Windows, Japanese
28491 InterBase XE 64-bit Update 3 (10.0.3.566) for Windows, English
28493 InterBase XE Update 3 (10.0.3.566) 32-bit ToGo Edition, Windows, English
28495 InterBase XE Update 3 (10.0.3.566) 64-bit ToGo Edition, Windows, English
28533 InterBase XE Update 3 (10.0.3.566) for Linux, Japanese
28500 InterBase XE Update 3 (10.0.3.566) for Linux, English
28501 InterBase XE Update 3 (10.0.3.566) for Mac OS X, English

28529 InterBase XE (10.0.3.566) 32-bit Developer Edition for Windows, Japanese
28502 InterBase XE (10.0.3.566) 32-bit Developer Edition for Windows, English
28527 InterBase XE (10.0.3.566) 64-bit Developer Edition for Windows, Japanese
28503 InterBase XE (10.0.3.566) 64-bit Developer Edition for Windows, English
28535 InterBase XE (10.0.3.566) 32-bit Developer Edition, Linux, Japanese
28504 InterBase XE (10.0.3.566) 32-bit Developer Edition, Linux, English
28505 InterBase XE (10.0.3.566) 32-bit Developer Edition, Mac OS X, English

2011/10/08追記: 日本語版のUpdate 3がリリースされたのでリンクを追加しました。

2011/10/09追記: Team Japanのアーティクルのリンクを追加しました。

2011/10/18追記: "IBConsole enhancements in InterBase XE Update 3"のリンクを追加しました。

2011/11/14追記: "InterBase XE Update 3 での IBCosole の機能強化"のリンクを追加しました。

2011年9月20日

TStopwatchその2

時間がだいぶ経ってしまったのですが、TStopwatchに関するアーティクル
経過時間を示すElapsed/ElapsedMilliseconds/ElapsedTicksプロパティはStopメソッドで停止した状態でないと更新された値を取得できない。
という記述について、山本さんほかから停止状態じゃなくても正しい値が取れるのでは?(意訳)という指摘がありました。そこでDelphi 2010/XE/XE2で実装を確認してみましたが、確かにどのバージョンでも停止状態になくても特に問題なく正しい値を取得できるようです。またDiagnostics.TStopWatchの元ねたである本家.NET FrameworkのSystem.Diagnostics.Stopwatch.Elapsedでもやはり状態に関わらず適切な値を取得できるという記述になっています。ということでElapsed/ElapsedMilliseconds/ElapsedTicksプロパティは動作状態にかかわらず正しい値を取得できる(=ヘルプの記述が正しくない)、と考えてよさそうです。ではこのヘルプの記述(わざわざ注記してある内容が正しくない)はどこからきたのでしょう?いろいろ調べてみると、これはどうもdelphi.about.comのZarko Gajicさんの

High Performance Timer in Delphi - TStopWatch - High-Resolution Counter

という記事にある実装がDelphiにおけるTStopWatchの最初のもので、この実装では停止状態でしか正しい値を取得できないことに由来するのではないかと思われます。その後(おそらくVCLに取り込まれた後に).NET FrameworkのSystem.Diagnosticsに合わせて停止状態でも正しい値が取得できるように仕様が変更されたときにヘルプを修正し忘れた、ということではないでしょうか。

ということで大変遅くなりましたが元記事のほうも記述を修正しておきました。山本さんほか指摘していただいた方(確か全力わはーの中の人がtweetしてたような…?違ったらすいません)、2ちゃんねるでツッコミいれてくれた方、ありがとうございます。

2011年9月19日

RAD Studio/Delphi XE2ユーザ向Delphi Developer Certification無償キャンペーン

RAD Studio/Delphi XE2ユーザ向のDelphi Developer Certificationの無償キャンペーンが行われています。

Delphi Insider: Free Certification Test for Delphi XE2 and RAD Studio XE2 Users
Limited Time Special

2011/09/30までに新規購入かアップグレードを行い、2011/10/15までにプロモーションページで登録することで、無料でDelphi Developer Certificationを受けることができます。受験は登録から90日以内となっています。

また前回のキャンペーンによる受験は2011/07/31登録でも2011/10/29が期限になります。期限切れに注意しましょう。

2011年9月16日

プログラミングの魔導書Vol.2 予約受付開始

プログラミングの魔導書 ~Programmers' Grimoire~ Vol.2の発売がアナウンスされています。Vol.1の発売から早一年、ひょっとして一発で終わってしまったのかと心配していましたが、無事にVol.2の予約の受付が始まったようです。

株式会社ロングゲート - 製品案内

お知らせ

受注生産の形態をとっているため、書籍版に関しては予約でのご注文のみとなりますのでご注意ください。

PDF版は予約期間が過ぎた後でもご購入いただけます。

予約期間は2011/10/04(火)までです。

Gmailでは、ダウンロード開始メールが迷惑メールフォルダに格納されてしまう場合があります。PDF版を購入し、ダウンロード開始メールが届かない場合、そちらをご確認ください。

元ねたは『プログラミングの魔導書 Vol.2』予約開始! - Faith and Brave - C++で遊ぼう本の虫: プログラミングの魔導書 Vol.2の予約受付中

2011年9月14日

Microsoft Monthly Update 2011/09

今日はMicrosoftのセキュリティアップデートの日です。
MS11-070
MS11-071
MS11-072
MS11-073
MS11-074

2011年9月11日

[書籍]プログラミングの心理学 25周年記念版

ジュンク堂書店 新宿店The Psychology of Computer Programming: Silver Anniversary Editionの翻訳(新訳)である

プログラミングの心理学 【25周年記念版】 (amazon)/Gerald M. Weinberg著/伊豆原弓訳/日経BP/ISBN 978-4-8222-8470-1/2,730円

を購入。さすがに内容は古いですね。PL/IとかCOBOLなんて聞いたこともない人にはお勧めしません。それくらいなら同じWeinberg先生のライト,ついてますか (amazon)をお勧めします。

2011年9月6日

第20回エンバカデロ・デベロッパーキャンプ開催

本日(2011/09/06)の10:00からデベロッパーキャンプが行われます。David Iさんも一昨日の夜に来日しています。

David I、デベロッパーキャンプ参加に向け来日

会場は秋葉原UDXの4Fです。

Team Japan » 第20回 エンバカデロ・デベロッパーキャンプ - 会場へのアクセス

こちらは残念なお知らせです。

第20回エンバカデロ デベロッパーキャンプで喋れなくなりました。 - C++Builder好きの秘密基地

この枠はどうなるのかな?高橋さんのDBXのセッションのみになる模様です。

会場到着。あと10分で開始です。

10時です。始まりました。今日はUStream中継もあるようです(全てではないG/AセッションのみでBはなしの模様)。

懇親会ただの飲み会を含め、無事終了。参加者のみなさん、スピーカのみなさん、関係者のみなさん、おつかれさまでした。David Iさんほか明日神戸に行かれる方々はお気をつけて。ちなみに次回の開催日程はまだ未定だそうです(年内はないんですか?って聞いてみたけど、う~ん、という反応でした)。

2011/09/15追記: セッション資料がダウンロードできるようになっています。

第20回 エンバカデロ・デベロッパーキャンプ - セッション資料ダウンロード

2011/11/30-2011/12/06追記: David IさんのA5 Delphi/C++Builderテクニカルセッション 「RAD Studio XE2によるクロスプラットフォーム開発」のリプレイビデオが公開されています。日本語字幕入りです。

ビデオ - 第20回 エンバカデロ・デベロッパーキャンプ 「RAD Studio XE2 によるクロスプラットフォーム開発」
「RAD Studio XE2によるクロスプラットフォーム開発」 1/5 - YouTube
「RAD Studio XE2によるクロスプラットフォーム開発」 2/5 - YouTube
「RAD Studio XE2によるクロスプラットフォーム開発」 3/5 - YouTube
「RAD Studio XE2によるクロスプラットフォーム開発」 4/5 - YouTube
「RAD Studio XE2によるクロスプラットフォーム開発」 5/5 - YouTube

2011年9月5日

ISO/IEC 14882:2011 (C++ 2011)発行

C++0xことC++2011がついにISO/IEC 14882:2011として発行されました。

ISO/IEC 14882:2011 - Information technology -- Programming languages -- C++

あとはC++Builder XE3でC++2011がどれだけサポートされるか、でしょうかね。

元ねたはC++11が正式に発行されました - Faith and Brave - C++で遊ぼう

2011年9月3日

DDevExtensions 2.5リリース

Andreas HausladenさんDDevExtensionsがアップデートされてVersion 2.5になっています。Delphi XE2のサポートなどが追加されています。

DDevExtensions 2.5 with XE2 support | Andy’s Blog and Tools

2011年9月2日

Oxygene for Java

Project "Cooper"ことOxygene for Javaについての続報です。

Oxygene for .NET = Embarcadero Prism XE2 « RemObjects Blogs

RemObjects Oxygene 5はOxygene for .NETとOxygene for Javaで構成されており、このうちOxygene for .NETは(Embarcadero) Prism XE2 Professionalとして(Oxygeneとしては)単体で販売され、一方でOxygene for JavaはOxygene 5(599USD)あるいはOxygene for Java(399USD)単体でRemObjectsから発売予定(現時点でpre-order)、ということです。

2011/09/07追記: RemObjectsからOxygene 5が正式にアナウンスされています。

Announcing Oxygene 5 for .NET and Java « RemObjects Blogs

2011年9月1日

RAD Studio/Delphi/C++Builder/Prism/RadPHP XE2リリース

RAD Studio/Delphi/C++Builder/Prism/RadPHP XE2が正式にリリースとなったようです。トライアル版は既にダウンロード可能になっています。

Windows、Mac、Web、モバイル開発に対応したRAD Studio XE2登場!
エンバカデロ、開発ツール「RAD Studio XE2」とコンポーネント4製品を発売 - ニュース:ITpro

Delphi XE2 および C++Builder XE2 で修正された不具合一覧

2011/09/02追記: IPIndyImpl.dcp(Win64/OS X)とinetdbexpress.dcp(Win64/Release)が不足しているという問題(RAID287274)に対するhotfixがリリースされています。

28484 IPIndyImpl.dcp and inetdbxpress.dcp for Delphi XE2

2011/09/03追記: プロダクトマーケティングマネージャのTim Del ChiaroさんによるXE2のダウンロード関係のリンクのまとめです。

Delphi Insider: Download links for Delphi XE2, C++Builder XE2, RAD Studio XE2, Embarcadero Prism XE2 and RadPHP XE2

2011/10/04追記: Delphi/C++Builder XE2で修正された不具合一覧のリンクを追加しました。

RAD Studio/Delphi/C++Builder/Prism/RadPHP XE2リリース間近

いよいよRAD Studio/Delphi/C++Builder/Prism/RadPHP XE2のリリースが迫っているようです。とりあえずプレスリリース、インストール/リリースノートなどのリンクを。

プレスリリース: エンバカデロ、Delphi / C++Builder / RAD Studioの新バージョン 「XE2」によりビジネスアプリケーション開発を変革



過去のバージョンのライセンスの件については、

以前の製品バージョンのインストール

ライセンスには次に示す以前の製品バージョンが含まれ、それらをダウンロードして使用できます。

  • Delphi XE2 は、Delphi XE、2010、2009、2007 および 7 の各ライセンスを含みます。
  • C++Builder XE2 は C++Builder XE、2010、2009、2007 および 6 の各ライセンスを含みます。
  • RAD Studio XE2 は、Delphi および C++Builder の全バージョンのライセンスを含みます。

個人指名ユーザー ライセンスまたは複数の指名ユーザー ライセンス(5 ユーザー パックまたは 10 ユーザー パック)を購入した場合:

XE2 製品をインストールし、登録した後に、「以前のバージョン」にアクセスして、古いバージョンの Serial Number とソフトウェア(ダウンロード)を入手できます。XE2 製品の購入後 180 日以内に、このページから、古いバージョンのライセンスを要求する必要があります。

XE2 製品に対して、ネットワーク指名ユーザー ライセンス、AppWave 指名ユーザー ライセンス、または同時使用ライセンスを購入した場合:

ユーザーのネットワーク ライセンス証明書に、Delphi 7 や C++Builder 6 の個人 Serial Number を含め、2007 から XE の各バージョンでライセンス処理に使用するスイート ライセンスが含まれます。Delphi 7 および C++Builder 6 の Serial Number は、単一の指名ユーザー Serial Number です。ユーザー間で移転はできず、ライセンス サーバー経由での同時ユーザー アクセスに利用できません。

メモ:アカデミック版には、以前の製品バージョンのライセンスは含まれません。

、XEと同様の条件になっています。いう記述がDelphi XE2 および C++Builder XE2 のリリース ノートDelphi XE2 および C++Builder XE2 のインストール ノートにはありますが、RAD Studio XE2 Q&Aでは

旧バージョンのライセンスリクエストには、180日以内という制限があるのですか?

XEで設けられていた180日以内という制限は、XE2では設けていません。新バージョンでは、購入後180日以降でも、問題なくライセンスリクエストを行えます。

となっており、XEとは扱いが異なるようです。

またオンラインヘルプも参照可能になっています。

Online Help for Delphi XE2 and C++Builder XE2
Delphi XE2 および C++Builder XE2 オンライン ヘルプ

2011年8月30日

IntraWeb 9が無償に

DelphiにはIntraWeb(VCL for the Web)がバンドルされていますが、ANSI版Delphi(5/6/7/2005/2006/2007)に対応しているIntraWeb 9 Enterprise(9.0.42)をAtozed Softwareが無償で公開しています。

Atozed Software - IntraWeb 9 Enterprise is now free!

Atozedでアカウントを作成するだけでIntraWeb 9 Enterpriseのライセンスを取得することができるようになります。ただしANSI版のみ、バグ修正なし、サポートなしとのことです。

2011年8月29日

[書籍]Delphi Developer's Guide to XML, 2nd Edition

2003/12/31発行と少々古めの本ですが、Amazon.co.jpで注文した

Delphi Developer's Guide to XML, 2nd Edition (BookSurge/amazon)/Keith Wood著/BookSurge Publishing/ISBN 978-1591098621 (ISBN 1591098629)/49.95USD(4,971JPY)

が配送されてきました(堺配送センター発で今回の配送は佐川急便)。

2011/09/02追記: Amazon.co.jpは売り切れのようですね。円高ですし、送料込みでもAmazon.comなら4,500JPY程度で買えるのではないでしょうか。

IDE Fix Pack 4.4リリース

Andreas HausladenさんIDE Fix Pack 2007およびIDE Fix Pack 2009/2010/XEがアップデートされてVersion 4.4になっています。

IDE Fix Pack 4.4 released | Andy’s Blog and Tools

2011年8月25日

Webセミナー 9月まで待てない!デベロッパーキャンプ・プレセミナー 第3回 - 「第20回 エンバカデロ・デベロッパーキャンプ先取り情報」

9月まで待てない!デベロッパーキャンプ・プレセミナー 第3回 - 「第20回 エンバカデロ・デベロッパーキャンプ先取り情報」

第20回エンバカデロ・デベロッパーキャンプの開催概要についての説明。会場(秋葉原UDX)について。USスピーカのDavid Iさんについて。タイムテーブルについて。

G1 オープニングセッションはAppWaveについて。Team JapanAppWave - 「クライアントアプリ+ODBCドライバ+DSN」をパッケージ化可能ですも参照。

G2 ジェネラルセッションはRAD Studio XE2について。先行販売の案内も。

A3 Delphi/C++BuilderテクニカルセッションはRAD Studio XE2のDeep Dive。FireMonkey、クロス開発など。

B3 PHPテクニカルセッションはRadPHP XE2。モバイル開発、PhoneGap。

A4 Delphi/C++Builderテクニカルセッションは筑木さんによるVCLについてのあまりドキュメント化されていない/知られていない機能などについての解説。

A5 Delphi/C++Builder/PrismテクニカルセッションはRAD Studio XE2によるクラスプラットフォーム開発について。高橋さんによるMacOS X上でのリモートデバッグの方法についてのデモ。あらかじめPlatform Assistant ServerをMac OS上にインストールしておき、FireMonkeyプロジェクトを作成してターゲットプラットフォームにOS Xを追加してビルド、実行しようとするとリモートプロファイルを要求されるのでウィザードでパラメータを入力してプロファイルを作成、これで実行すれば必要なファイルの転送、リモートデバッグもあら簡単。FireMonkeyなら2D/3Dも同じように動作。

G6 ライトニングトーク。博士とドラ娘。過去のダイジェスト。参加者募集中。

懇親会もまだ参加者募集中。既にデベロッパーキャンプ申し込み済の人は同じメールアドレスで再度申し込みすればOK。

Q&A: RAD Studio XE2でもXEと同様に過去のバージョンも使えるライセンスになるとのこと。FireMonkeyアプリケーションでもIndy、SOAPクライアント、DataSnapなどネットワーク関係の機能はそのまま使える。VCLとFireMonkeyは"似ている"程度の関係。WindowsとMacOSの違いもあるので個別の対応はいずれにせよ必要。

終了。お疲れさまでした。TweetのまとめはTogetter - 「9月まで待てない!「第20回エンバカデロ・デベロッパーキャンプ先取り情報」」

RAD Studio XE2 スニークプレビュー その1

とりあえずメモ。後で追記予定。

while true do; » Blog Archive » DataSnap Mobile Connectors in RAD Studio XE2
FireMonkey Video Beta Blog
program begin end. // comments?: RAD Studio XE2 - VCL and FireMonkey (FMX) first glance comparison
Rob’s Technology Corner: New Mac and Rad Studio XE2
Native Zip file support in Delphi XE2 | TwoDesk Delphi Blog
64-bit VCL in Delphi XE2 | TwoDesk Delphi Blog
while true do; » Blog Archive » In the core of LiveBindings expressions of RAD Studio XE2
Glooscap Software: Delphi XE2 - A few of my favourite things...
Paweł Głowacki : New "TOSVersion" type in Delphi XE2
Oxygene on RemObjects TV | RemObjects Software
VCL Styles in Delphi XE2 | TwoDesk Delphi Blog
program begin end. // comments?: Forms and Data Entry Validation - Part 1
Michael Swindell » In The Words of FireMonkey Developers
RAD Studio XE2 – Setting it up for a Mac (step-by-step illustrated guide) | Reinvent The Wheel
Delphi Insider: VCL Styles in Delphi, C++Builder and RAD Studio XE2

2011年8月24日

Firebird 2.5.1 Release Candidate 1リリース

Firebird 2.5.1 Release Candidate 1がリリースされています。

Firebird: Firebird 2.5.1 Release Candidate 1 Binary Kits (download)
Firebird 2.5.1 Release Notes

MacOS X版はLion(10.7)における問題が解決次第リリースされるとのことです。

元ねたはFirebird News » Firebird 2.5.1 RC1 packages are ready.

2011/08/25追記: 正式にアナウンスされています。

Firebird: Firebird 2.5.1 Release Candidate Available

2011/09/10追記: Mac OS X 64bit版がリリースされています。

Firebird: Firebird for MacOSX updates: 2.5.1 RC1 and 2.5.0 64-bit builds

2011/09/16追記: Mac OS X 32bit版がリリースされています。

Firebird: Firebird 2.5.1 RC1 MacOSX 32-bit Builds Available

2011年8月16日

RAD Studio XE2の新機能

エンバカデロ・テクノロジーズのチーフエバンジェリストのDavid Iさん

Sip from the Firehose : Want more…Satisfaction

というアーティクルでRAD Studio XE2の新機能について書いています。

以下てきとうな訳です。
  • コンパイラ/フレームワーク
    • Delphi 64bitコンパイラ
    • Delphi OS Xコンパイラ (32bit)
    • C++ OS Xコンパイラ (32bit)
    • FireMonkeyプラットフォーム/Windows x86 (Windows XP/Vista/7/Server 2003/Server 2008/Server 2008 R2)
    • FireMonkeyプラットフォーム/Windows x64 (Windows XP/Vista/7/Server 2003/Server 2008/Server 2008 R2)
    • FireMonkeyプラットフォーム/OS X (10.6/10.7)
    • FireMonkeyプラットフォーム/iOS (4.2以降)
    • VCL/Windows x64 (Windows Vista/7)

  • IDE
    • IDEで64bit Windows向プロジェクトの構築/管理をサポート
    • IDEでOS X向プロジェクトの構築/管理をサポート

  • RTL/RTTI関係
    • 64bit Windows向Delphi RTL
    • OS X向Delphi RTL
    • OS X向C++ RTL
    • zipファイルサポート
    • RTTIでインデックス付プロパティとRTLをサポート
    • DelphiでC++のRTTIとの互換性
    • OS X向C++ Boost
    • OS X向Dinkumware製C++ RTL

  • デプロイメントマネージャ
    • DelphiアプリケーションをOS X、Windows x86、Windows x64に配布
    • C++アプリケーションをOS X、Windows x86に配布
    • Delphi/C++アプリケーションをAmazon EC2、Windows Azureに配布

  • QA測定(audits)/QA検査(metrics)
    • 測定でDelphiのポインタを解析
    • C++を測定
    • C++で静的コード検査

  • デバッグ
    • DelphiのWindows x64アプリケーションをデバッグ
    • Delphi/C++のOS Xアプリケーションをデバッグ

  • dbExpress
    • Windows x64で全てのdbExpressドライバを使用可能
    • InterBase、Firebird、Oracle、MySQL、SQL Anywhere、InformixのOS X用dbExpressドライバ
    • ODBCドライバ

  • LiveBindings
    • LiveBindingsであらゆる型のデータとVCL/FireMonkeyのあらゆるUI/グラフィック要素を接続

  • DataSnap
    • スタンドアロンDataSnapアプリケーションでHTTPSをサポート
    • DataSnapサーバでsocket接続を強制終了可能に
    • HTTPでCommunicationTimeoutを指定可能に
    • ディスパッチでJavaScript最小化
    • ヘビーウェイトコールバックでブロードキャストをサポート
    • サーバ/クライアントでコールバックチャンネルイベント
    • RESTサーバでマルチプルコールバックトンネルをサポート
    • TCP/IP上でセッションイベント
    • TCP転送コンポーネントでKeepAliveをサポート
    • 接続をモニタ/制御
    • DataSnapウィザードのソースコード(自作のウィザードを作れるように)
    • ClientDataSetがWindows x64とOS Xをサポート
    • Windows x64、OS X、Windows Phone 7用デスクトップクライアント接続
    • iOS、Android、BlackBerry、Windows Phone 7用モバイルクライアント接続

  • InterBase
    • InterBase XEデベロッパエディション(20ユーザ、80接続まで)

  • クラウドコンピューティング
    • TAzureQueueManagementでメタデータをサポート
    • Amazon Simple Storage Service(Amazon S3) API
    • Amazon Queue Service API
    • Amazon SimpleDB API

  • コンポーネント/ライブラリ
    • FastReport VCL 4 RADエディション (レポートツール)
    • Documentation Insight (XMLドキュメンテーションツール)
    • Windows x64/OS X用Indyコンポーネントライブラリ
    • Windows x64用ActiveX for Delphi
    • VCLでWindows x64をサポート
    • VCLにスタイル機能

  • Prism
    • RemObjects Oxygeneコンパイラ5.0
    • FastReport.net (レポートツール)

  • RadPHP
    • モバイルに最適化されたwebアプリケーションをビルド
    • デバイス上での表示を確認できるビジュアルモバイルデザインサーフェイス
    • PHPアプリケーションをiOS/Androidのネイティブアプリケーションに変換 (おそらくPhoneGap (wikipedia)を利用)
    • jQueryモバイルコンポーネント

2011年8月13日

C++ 2011標準規格承認

FDISとなっていたC++0xに対してISOのナショナルボディによる投票が行われ、全会一致で承認された、というニュースが入ってきました。

Sip from the Firehose : C++ 2011 standard approved by unanimous vote
C++0xが国際標準C++11へ。 - Faith and Brave - C++で遊ぼう
We have an international standard: C++0x is unanimously approved « Sutter’s Mill

これによりC++0xはC++ 2011として今年中にもISOの正式な規格として公開されることになるものと思われます。

一方でC++BuilderにおけるサポートはDavid Iさんが書いているように、来年リリースされる(ことになると思われる)XE3で、ということのようです(XE2は既にRTM寸前ですから)。MicrosoftのVisual C++はどうなるんでしょうか?

2011年8月9日

[書籍]ストラウストラップのプログラミング入門

C++の生みの親、禿校長先生Bjarne Stroustrupさんによるプログラミングの入門書、Programming: Principles and Practice Using C++ (amazon)の日本語版が遂に発売になりました。ということでブックファースト 渋谷文化村通り店で購入。

ストラウストラップのプログラミング入門 (amazon)/Bjarne Stroustrup著/遠藤美代子(株式会社クイープ)訳/επιστημη監修/翔泳社/ISBN 978-4-7981-1959-5/8,190円

どうも2分冊にするかどうかで混乱があったようですが、結局原著と同様に1100ページ超、厚さ50mmという凶器として無事に出版となったようです。しかし技術系書籍の編集者のタイトルをつけるときのセンスのなさといったら…普通に翻訳するだけでいいのに、なぜそれより酷い日本語を付け足すのかなぁ。この本はタイトルで売る本じゃないだろうに。

2011年8月8日

TStopwatch

Delphi 2010でDiagnosticsユニットが追加され、システムが高分解能パフォーマンスカウンタをサポートしていればQueryPerformanceCounter (ja)を利用し、サポートしていない場合はGetTickCount (ja)で代用することでストップウォッチ機能を(高分解能パフォーマンスカウンタ機能の有無に関わらず)統一的に扱うことができるTStopwatchレコードが使用できるようになっています。

TStopwatchの注意点としては
  • TStopwatchはレコード型であるにもかかわらず内部状態の明示的な初期化のためにconstructorclass function Createまたはclass function StartNewの明示的な呼び出しが必要(デストラクタの呼び出しは不要明示的に定義されたコンストラクタ、デストラクタは存在しない)。
  • 経過時間を示すElapsed/ElapsedMilliseconds/ElapsedTicksプロパティはStopメソッドで停止した状態でないと更新された値を取得できない計測状態、停止状態に関わらず正しい値を取得できる。
といったところでしょうか。基本的にはユニット名(Diagnostics=診断)のとおりデバッグ時などのパフォーマンス計測用と考えればよいと思います。

元ねたはMarco CantuさんDelphi 2010 Handbook

2011/09/20追記: TStopwatchその2に書いたように、状態に関わらずElapsed/ElapsedMilliseconds/ElapsedTicksプロパティは正しい値を取得できること、またCreateはconstructorではなくclass functionであることなど記述を修正しました。

2011年8月5日

RAD Studio/Delphi/C++Builder XE2情報

昨日(2011/08/04)のオークランドのWorld Premiereでワールドツアーが始まり、PulsarことRAD Studio/Delphi/C++Builder XE2の情報が少しずつ明らかになってきています(例年通りなら来週くらいからスニークプレビューも始まるのではないかと思います)。そこで現時点での情報をまとめていきます。

  • FastReportsがバンドルされる。
    公式フォーラムのEmbarcadero Discussion Forums: Nevrona Today?のBrent Roseさんの発言によれば、レポートツールとしてFast Reports Inc.のFastReportsがバンドルされることになったようです(消息不明の状況が続いているNevronaのRaveReportsも継続してバンドルされる模様)。
  • MacOSXおよびiOSアプリケーションを作成できるようになる。
    Rodrigo Ruzさんのtweet経由でSteve MaughanさんDelphi Firemonkey DemoDelphi For Macのデモビデオによると、Delphiプロジェクトとして従来のものに加えて"FireMonkey 2D Application","FireMonkey 2D iOS Application","FireMonkey 3D Application","FireMonkey 3D iOS Application"の4種類が追加されています(FireMonkeyはKSDevのVGScene/GLSceneをベースに新たに開発されたクロスプラットフォームUIライブラリで、WindowsではDirectXベース、MacOSX/iOSではOpenGLを使い2D/3D描画を行うものとのことです)。"FireMonkey 2D Application"と"FireMonkey 3D Application"は従来通りのDelphi IDE上での開発(MacOSXでは"Platform Assistant Server"によるリモートデバッグ)になりますが、"FireMonkey 3D iOS Application","FireMonkey 2D iOS Application"はMacOSX上のXCODEで実際のコンパイル、リンクを行うことで、MacOSX/iOS上で動作するアプリケーションを作成するためのもののようです。
    またエンバカデロのラテンアメリカ・カリブ地域担当プロダクトラインマネージャ・リードエバンジェリストのAndreano LanusseさんVideo: Delphi XE2 and FireMonkey app on Windows, Mac and iOS | Andreano Lanusse Blog | Technology and Software Development | DelphiのデモビデオによるとMacOSX上のXCODEへのプロジェクトのエクスポートはDelphi IDE上からメニューを選択するだけで簡単に行えるようです。
  • Windows x64サポートが追加される。
    予定通りVCL/FireMonkeyアプリケーションでWindows x64がサポートされます。
  • LiveBindingsであらゆるクラスのプロパティを関連付けることができるようになる。
    LiveBindingsを使用すると単純にインスタンスのプロパティ同士を関連付けるだけでなく、エクスプレッションエンジンによる評価値を表示させたり(この場合は単方向)、あるいは双方向にバインドすることもできます。またこのエクスプレッションエンジンはLiveBindingsからは独立しており、実行時に動的にObjectPascalを評価させることが可能とのことです。
  • RadPHPでAndroidのネイティブアプリケーションを作成できるようになる。
    RadPHP上でjQueryとPhoneGapを使用することでAndroid上で動作するネイティブアプリケーションを作成することができるようです。PhoneGapとはWikipedia (ja)によるとJavaScript、HTML、CSSを使ってモバイルアプリケーションを作成できるオープンソースのフレームワークとのことです。
  • Starter SKUも用意される。
    Pro/Ent/Arc SKUからは遅れるものの、XE2でもStarter SKUが用意されます。Starter SKUでもクロスプラットフォームは使用可能とのことです。
  • FireMokeyと従来のVCLはネームスペースで区別される。
    従来のVCLはVCL、FireMonkeyはFMXというネームスペースに含まれるようになり、これで区別されることになるようです。
  • DataSnapのクライアント側のプロキシを自動的に生成できるようになる。
    Objective-C、C#、Prism、BlackBerryなどからDataSnapサーバに接続するためのプロキシを自動的に生成することができるようになるとのことです。


元ねたは上記のリンクの他にJolyon SmithさんTe Waka o Delphi · RAD STUDIO XE2: Launch Event Report

2011/08/08追記: とりあえず現時点での情報をまとめました。

2011年8月2日

RAD Studio XE2 World Tour 2011

RAD Studio/Delphi/C++Builder XE2とそのお披露目のワールドツアーがアナウンスされています。まずは関係リンク。

RAD Studio XE2 World Tour
Sip from the Firehose : Want more…RAD Studio XE2
Delphi Insider: Win a copy of RAD Studio XE2 before you can buy it

RAD Studio XE2 and you | Reinvent The Wheel
A little bit about FireMonkey and Delphi XE2 | Andreano Lanusse Blog | Technology and Software Development | Delphi
FireMonkey Logo and Info (by Andreano)

Delphi / C++Builder / RAD Studioユーザー向け「XE2」先行販売のご案内

DelphiでMac向け開発。ネイティブクロス開発に踏み出すDelphi/C++Builder:Allegro Barbaro:ITmedia オルタナティブ・ブログ

発売は2011/09/01以降になる(2011/08/31以前ではない)模様です。既に特別バージョンアップ(2007/2009/2010/XEから)、ジャンプアップ(1.0~2006から)のキャンペーンもアナウンスされています。ところでXEの旧バージョンを利用できる件はXE2ではどうなるんでしょう。そしてStarter SKUについてもまだアナウンスがありませんは他のSKUから遅れて登場するようです(x64/MacOS XサポートやFireMonkeyなども含まれる模様)。

RAD Studio/Delphi/C++Builder XE2の新機能は以下の通り。
  • FireMonkeyと呼ばれる新しいUIフレームワークでHD/2D/3D描画をサポート
  • Delphiでx64をサポート
  • 単一ソースからプラットフォームを切り替えるだけでWindowsとMacOS Xのバイナリを生成(MacOS Xはクロス開発、リモートデバッグ)
  • DataSnapをモバイル、クラウド用に拡張(RAD Cloud)
  • LiveBindingsと呼ばれる新しいバインディングメカニズムで全てのビジュアル要素とデータソースを接続(DB系コンポーネントが不要に?)
  • VCLのルックアンドフィールをモダンなものに
  • RadPHPでモバイルデバイスに最適化されたwebアプリケーションやiOS/Androidデバイスのスタンドアロンアプリケーションを開発可能に
(以上意訳)

ワールドツアー(RAD Studio XE2 World Tour)は2011/08/04のオークランド(Auckland/NZ)でスタートし、2011/10/04のオーフス(Aarhus/DK)まで約2ヶ月に渡って各地でプロモーションが行われます。日本では2011/09/06の第20回エンバカデロ・デベロッパーキャンプがワールドツアーの一部、ということになります。また2011/09/12-14(PDT)にカリフォルニアのサンホセ(San Jose,CA/US)で行われるDelphi Live 2011でもプロモーションを行うようです。

またRAD Studio XE2のArc/Ent/Pro SKUがそれぞれ1名に当たるという抽選も行われます。申し込み期限は2011/08/31 23:59:59(PDT)です。詳しくはこのページの右上、"Enter to win a free copy of RAD Studio XE2 before you can buy it!"のリンクから。

さらに2011/08/04 17:00(JST)から開催のwebセミナー、9月まで待てない!7~8月はデベロッパーキャンププレセミナー 第2回 - 再演!「PHP Live! - ゼロから始めるPHPアプリの構築からデプロイまで」RadPHP XE2がチラっと見られるようです。

2011/08/04追記: 記事を更新しました。ワールドツアーの劈頭、オークランドはもう今日の09:00(NST)=06:00(JST)からです。

2011/08/04追記: オークランドのラウンチイベントをTe Waka o DelphiのJolyon Smithさんがレポートしています。

Te Waka o Delphi · RAD STUDIO XE2: Launch Event Report

2011年7月28日

RAD Studio/Delphi XEユーザ向Delphi Developer Certification無償キャンペーン締切間近

忘れかけていましたが、Delphi Certification ProgramDelphi Developer CertificationのRAD Studio/Delphi XE(Academicを除く/Starter SKUは含まれる)登録ユーザ向の無償キャンペーンの締め切り(2011/07/31)が迫っています。Delphi Certification FAQsQ: What is the free exam offer for registered Delphi XE and RAD Studio XE users?にあるように、プロモーションページでシリアル番号を入力することで無償テストコードを受け取り、そこから90日以内であれば"Developer Certification"を受験することができます。当然英語ですが、Delphi Developer Certification Exam Study Guideにあるサンプル問題程度の難易度ですので、それほどハードルは高くないと思います。

2011/07/31追記: 現時点(23:47)で上記のプロモーションは既に受け付けられない状態になっています。まぁそもそもどこの標準時を基準にしているのかも書いていない話なのでアレですが、日本人の感覚からするといかがなもんかなぁと。PDTベースだとまだ16時間もあるわけだし。

2011/08/02追記: 公式フォーラムのEmbarcadero Discussion Forums: Free Exam Offer for Delphi XE and RAD Studio XE Users, can't get test codeの情報によると現時点(2011/08/02 13:50JST)でプロモーションページが再びオープンとなっています。いつまでこの状態が続くのかはわかりませんが、まだ申し込んでいない方はお早めに。

2011年7月27日

Michael RozlogがEmbarcaderoを退職

DelphiプロダクトマネージャだったMichael Rozlogさんが2011/07/29(今週末ですな)でエンバカデロ・テクノロジーズを退職することを明らかにしました。

Michael Rozlog » Blog Archive » The time as come…

This is my last blog post for Borland/Inprise/Borland/CodeGear/Embarcadero as Friday the 29th is my last day.ということだそうです。ちょうど一年前のNick Hodgesさんの一件といい、新バージョンのリリース直前にマネージャが抜けるってのはどうなんでしょうね。直接XE2との関係はなさそうです(追記参照)。

Michael Rozlogさんの新しいblogは

TECHMANA

で、2011/07/30スタートとのことです。

2011/07/28追記: EDNプログラムマネージャだったJohn Kasterさんも2011/12/27でエンバカデロ・テクノロジーズを退職していたんですね。いまごろ気付きました。John Kasterさんの新しいblogは

John Kaster

です。

2011/07/30追記: Michael Rozlogさんは2011/01からセールスに異動していたようで、それが理由では?という見方もあるようです。というわけで一部修正。

2011年7月26日

TListの新しいメソッドSortList/IndexOfItem/ExtractItem/RemoveItemとTDirection

Delphi 2010でTListクラスにSortListIndexOfItemExtractItemRemoveItemというメソッドが追加されています。

TList.SortListはQuickSortの比較関数を"const TListSortCompareFunc" = "reference to function(Item2: Pointer, Item1: Pointer): Integer;"、つまり無名メソッドで渡すことができる、というもので、従来のSortのように比較関数を別途記述する必要がありません。たとえばフォーム上にTButtonとTMemoをひとつずつ配置しておき、
type
  TTestItem = class(TObject)
  private
    FNum: Integer;
    FStr: String;
  public
    constructor Create(ANum: Integer; const AStr: String);
    property Num: Integer read FNum;
   property Str: String read FStr;
  end;

constructor TTestItem.Create(ANum: Integer; const AStr: String);
begin
  inherited Create;
  FNum := ANum;
  FStr := AStr;
end;

procedure TForm1.Button1Click(Sender: TObject);

  procedure ShowList(List: TObjectList; const Caption: String);
  var
    Index: Integer;
    TestItem: TTestItem;
  begin
    Memo1.Lines.Add(Caption);
    for Index := 0 to List.Count - 1 do
    begin
      TestItem := List.Items[Index] as TTestItem;
      Memo1.Lines.Add(Format('Num=%d Str=%s',
                             [TestItem.Num,TestItem.Str]));
    end;
    Memo1.Lines.Add('');
  end;

var
  List: TObjectList;
begin

  List := TObjectList.Create(True);
  try
    List.Add(TTestItem.Create(5,'Five'));
    List.Add(TTestItem.Create(3,'Three'));
    List.Add(TTestItem.Create(1,'One'));
    List.Add(TTestItem.Create(2,'Two'));
    List.Add(TTestItem.Create(4,'Four'));

    ShowList(List,'Before sort');

    List.SortList(
      function (Item1, Item2: Pointer): Integer
      begin
        Result := TTestItem(Item1).Num - TTestItem(Item2).Num;
      end);

    ShowList(List,'After sort (Num)');

    List.SortList(
      function (Item1, Item2: Pointer): Integer
      begin
        Result := CompareStr(TTestItem(Item1).Str,TTestItem(Item2).Str);
      end);

    ShowList(List,'After sort (Str)');

  finally
    List.Free;
  end;

end;
こんな感じでSortListのパラメータに直接比較関数を記述できます。無名関数の記述が気持ち悪い(セミコロンの付きかたが違う、とか)という点はともかく、比較関数そのものはわかりやすく書くことができます。

一方IndexOfItem/ExtractItem/RemoveItemはIndexOf/Extract/Removeに追加のパラメータとしてFromBeginning/FromEndという2値の列挙型TList.TDirectionを受け取り、これがFromBeginningならば対象アイテムを(従来通り)先頭から検索し、FromEndならば対象アイテムを末尾から検索するというバリエーションです(なぜオーバロードにせず別のシグネチャを与えたのかはわかりません)。

元ねたはMarco CantuさんDelphi 2010 Handbook

2011年7月25日

Windows Vista/Server 2008/7/Server 2008 R2でIPv6コンポーネントを無効にする

Windows Vista以降のOSではIPv4とIPv6がデュアルIPレイヤという形で統合されて実装されていて、IPv6が不要であってもアンインストールできなくなっています。そこでIPv6が不要な(あるいは邪魔な)場合にIPv6コンポーネントを無効にする方法(ただしIPv6のループバックインタフェースは無効にならないので注意)。とりあえずメモ。

診断ツール Fix it: Windows Vista、Windows 7、および Windows Server 2008 で特定の IPv6 (Internet Protocol version 6) を無効にする方法に関する問題

直接レジストリ
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\DisabledComponents
の値(DWORD)を、
  • 0: IPv6有効(デフォルト)
  • 0xFFFFFFFF: IPv6無効
  • 0x20: プレフィックスポリシーでIPv4を使用
  • 0x10: IPv6ネイティブインタフェース無効
  • 0x01: IPv6トンネルインタフェース無効
と書き換えても問題ありませんが、レジストリの書き換えを行ってくれるFix itウィザードも用意されています。

またIPv6を無効にするまでもないけれどもIPv4を優先に設定したいような場合はコマンドプロンプトから

netsh interface ipv6 show prefixpolicies
で表示されるプレフィックス"::ffff:0:0/96"(IPv4-Mapped IPv6 Address)が最優先になるように、管理者権限を持つコマンドプロンプトから

netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 100 4
(最後から2番目の値が優先度(大きいほうが優先)で最後の値が当該プレフィックスのラベル)とすればいいようです(こちらはIPv6を有効にしたWindows XPでも使えます)。デフォルトの設定に戻すときは管理者権限を持つコマンドプロンプトから

netsh interface ipv6 reset
として再起動します。

元ねたはセキュリティホール memo2011/07/12の記事と、IPv4 を IPv6 より優先にするおよびWindows 7でIPv4をIPv6に対して優先にする方法 - 徒然日記(2011-03-30)

2011年7月23日

DDevExtensions 2.4リリース

Andreas HausladenさんDDevExtensionsがアップデートされてVersion 2.4になっています。Delphi 2007/2009で[Shift]+[F3]による逆方向の検索ができるようになるなど、細かく新機能が追加されています。

DDevExtensions 2.4 | Andy’s Blog and Tools

2011年7月19日

デバッグ時にEIPを移動する

RAD Studio/Delphi/C++Builder 2010以降のIDEのデバッガ上でプログラムをデバッグ実行しているときに(ブレークポイントにヒットするなどして)実行が停止した状態で、次に実行する行を示す矢印(Instruction pointer symbol)を他の行にドラッグすることで任意の場所から実行を継続することができる、という機能が追加されています。同一ソースファイル上であれば別の関数のコードに移動することもできますが、実際に実行を継続すると概ねエラーになります(スタックの状態とか自動変数のことを考えれば当たり前ですけど)。

ヘルプを確認してみるとDelphi 2010 および C++Builder 2010 の新機能 - RAD Studio (日本語)のコード エディタの変更点の最後に
アイコンのドラッグ アンド ドロップ: コード エディタ ウィンドウの左マージン領域で、特定のアイコンを移動できるようになりました。 たとえば、
(略)
指示ポインタ記号: このアイコンは、(デバッグ中に)次に実行するコード行を示します。

とこっそりと書いてありますが、気づいていませんでした。過去のデベロッパーキャンプで聞いたことがあるような気もしますが、すっかり忘れていたのでとりあえずメモ。

元ねたはMarco CantuさんDelphi 2010 Handbook

2011年7月13日

Microsoft Monthly Update 2011/07

今日はMicrosoftのセキュリティアップデートの日です。
MS11-053
MS11-054
MS11-055
MS11-056

今回の更新をもって
  • Windows Vista Service Pack 1 (x86/x64)
  • Windows Server 2008 (RTM)
  • Office XP
  • .NET Framework 3.0/3.0 Service Pack 1/3.0 Service Pack 2/3.5
  • Exchange Server 2007 Service Pack 2
のサポートが終了になります。Windows Vista/Windows Server 2008についてはService Pack 2 (x86/x64)を、.NET Frameworkについては3.5 Service 1を、それぞれ適用することが推奨されています。元ねたはサポート ライフサイクル終了に伴うセキュリティ更新プログラム配信終了の予告 - 日本のセキュリティチーム - Site Home - TechNet Blogs

2011年7月11日

FindCmdLineSwitch関数

SysUtils.FindCmdLineSwitch関数はコマンドラインパラメータに特定のスイッチが指定されているかどうかを判定する関数で、Delphi 4以降に存在していますが、Delphi 2010までは特定のスイッチの有無を調べるだけで、それ以上のことをしようと思うと結局ParamCountParamStrのお世話になるしかなく、いま一つ使えない関数でした。ところがDelphi XEでは4つめのオーバロード関数が追加され、第4パラメータのSwitchTypesで指定した方法でスイッチのパラメータを取得できるようになり、使える関数になりました。これは非常に便利です。とりあえずメモ。

元ねたはMarco CantuさんDelphi XE Handbook

2011年7月8日

3rd anniversary

このblogを始めて丸3年になりました。当初は過疎blogでしたが、いまでは本家エンバカデロ・テクノロジーズからもリンクしていただくまでになり、ありがたく思っています。

さて、この1年間のエントリは205件(2010/07/08-2011/07/07)と週平均4エントリに迫っており、なかなか頑張った感じです。

2010/07にBloggerに追加されたアクセス解析の統計情報から月別ページビュー(PV)を。

2010/07: 4,267
2010/08: 4,518
2010/09: 4,854
2010/10: 5,547
2010/11: 5,149
2010/12: 5,570
2011/01: 5,291
2011/02: 6,010
2011/03: 5,587
2011/04: 6,308
2011/05: 6,950
2011/06: 6,882
2010/07-2011/06合計: 66,977

平均的には1日あたり平日は約250+PV、休日は約100+PVといったところでしょうか。またページ別ではWindowsのSNP(Scalable Networking Pack)を無効にするのPVが圧倒的に多く、このページだけで約5000+PV、全体の約8%を占めています。これはGoogle(jp)上の"SNP 無効"という検索で非常に上位に(それもGoogleがアルゴリズムの変更を行うまで元ねたの日本マイクロソフトのAsk the Network & AD Support Teamのアーティクルよりも上位だった)出てくるのが理由だと思われます。bing(us)では同一のキーワードでもそれほど極端に上位ではないので、Blogger上のコンテンツであることが有利に働いているのでしょう。次点はMS11-025によって発生する問題とその対策で、わずか2ヶ月で900+PVと、この問題がいかに影響が大きく、かつMicrosoftからの情報発信が不十分だったか、ということを物語っていると思われます。
一方、国と地域別では当たり前ですが90%以上を日本からが占めていて、アメリカ合衆国、オランダ、大韓民国と続いています。アンゴラやラトビアなどからは一時的に一定期間だけまとまったアクセスがあるので、これはプロキシとして利用されているのではないかと思っています。

今年はこの後RAD Studio/Delphi/C++Builder XE2(Pulsar)のリリースが控えています(8月とも9月ともいわれていますが、さて…)。去年からの宿題であるクロスプラットフォーム(MacOSサポート)やWindows x64サポートの第一歩になるDelphiのx64版など、なかなか楽しみです。

そういえばGoogleのPageRankは長らく"2"でしたが、数日前にふと確認したら"3"に成り上がっていました。これもご贔屓にしてくださっているみなさまのおかげです。

2011年7月6日

2011/07開催のウェブセミナー

2011/07/21 17:00-18:00(JST) 9月まで待てない!7~8月はデベロッパーキャンププレセミナー 第1回 - 再演!「今さら聞けない(?!)C/C++ポインター再入門」

第20回エンバカデロ・デベロッパーキャンプ開催決定

第20回エンバカデロ・デベロッパーキャンプは2011年09月06日に開催されます。

エンバカデロ・デベロッパーキャンプ
第20回 エンバカデロ・デベロッパーキャンプ

今回はエンバカデロ・テクノロジーズ チーフエヴァンジェリストのDavid I (David Intersimone)さんが来日して、RAD Studio/Delphi/C++Builder XE2(仮称、コードネームPulsar)についてディープなセッションを繰り広げる予定とのことです。またG6セッションは例によってはかせと銅鑼娘はやしさん司会の『ライトニングトーク「共有!みんなの開発事例、開発経験、テクニック」』で、参加者募集中だそうです。

また『9月まで待てない!7~8月はデベロッパーキャンププレセミナー 』というタイトルで3回に渡ってWebSeminarが行われます。第1回、第2回は以前のデベロッパーキャンプの再放送ですが、第3回はタイミング的に面白い話が聞けるかもしれません。

2011/07/21追記: プレセミナーは「再放送」ではなく「再演」なんですね。

2011/08/17追記: EDNの記事のリンクを追加しました。

2011年7月2日

[書籍]Delphi XE Handbook

Amazon.comで注文した

Delphi XE Handbook (Amazon US)/Marco Cantu著/CreateSpace/ISBN 978-1463600679/34.50USD

が配送されてきました(今回の配送は日本郵便でした)。2011/06/21に注文して11日目の到着、34.50USDにShippingの5.48USDで締めて39.98USD=3,233JPY(暫定)3,253JPY(1USD=81.366JPY)でした。

2011/07/17追記: 日本のamazonでも扱いが始まっています。

Amazon.co.jp: Delphi Xe Handbook: A Guide to New Features in Delphi Xe: Marco Cantu: 洋書

2,908円で送料がかからないので、円高が72円台に進んだりしなければamazon.co.jpのほうが安いですね。

2011/07/31追記: カードの利用明細によると3,253JPY(1.00USD=81.366JPY)で決済されました。amazon.co.jpでは2,836JPYで配送無料ですから、やはりこちらがお勧めです。

2011年7月1日

RAD Studio/Delphi/C++Builder XE Help Update 3

RAD Studio/Delphi/C++Builder XEのHelp Update 3がリリースされています。

Help Update 3 for Delphi XE and C++Builder XE now available
リリース ノート: Delphi XE および C++Builder XE Help Update 3
28256 Help Update 3 for Delphi XE and C++Builder XE

2011/07/03追記: リリースノートへのリンクを追加しました。お休みなのにごくろうさまです。

2011年6月20日

Delphi XE Handbook発売

Marco CantuさんDelphi XE Handbookが発売されました。今までのハンドブックとの内容の重複はなく、全132ページとなっています。書籍版はAmazon(US)から34.50USD(=2,768JPY)で、eBook版はFastSpringから20.00USD(=1,650JPY)で、購入することができます(eBook版については先週金曜日(2011/06/17)にMarcoさんのTwitterおよびFacebookのアカウントにpostされたディスカウントコードで5.00USD割引の15.00USD(=1,238JPY)になるとのことです)。

元ねたはDelphi XE Handbook Available

2011/06/22追記: Delphi Handbookシリーズの2007からXEまでを一つのeBookにまとめた"Delphi Handbooks Collection, Second Edition"も近日中にリリースされる予定とのことです。

Delphi Handbooks Collection, Second Edition (2007 to XE)

全1113ページで74.50USD(=5,974JPY)、同じくFastSpringで購入可能です(書籍版はページ数が多すぎて無理だそうです)。過去のeBook版の購入者にはディスカウントがあるそうです。

2011年6月14日

第20回エンバカデロ・デベロッパーキャンプ開催予告

第20回エンバカデロ・デベロッパーキャンプが2011/09/06開催で調整中とのことです。

エンバカデロ・デベロッパーキャンプ
次回のデベロッパーキャンプは、2011年9月6日に開催を予定しています。プログラムの詳細ならびに参加受付は、7月上旬より公開・開始させていただく予定です。ご期待ください。

またセッションスピーカ、ライトニングトークスピーカの募集も始まっています。

第20回 エンバカデロ・デベロッパーキャンプ セッションスピーカー募集中!
第20回 エンバカデロ・デベロッパーキャンプ ライトニングトーク スピーカー募集のお知らせ

2011/06/17追記: LTのネタについては熟慮中ということで…。なるべく早めの提出を心掛けたいと思います…。

2011年6月13日

[書籍]ユニコード戦記

MARUZEN&ジュンク堂書店 渋谷店

ユニコード戦記 文字符号の国際標準化バトル (amazon)/小林龍生著/東京電機大学出版局/ISBN 978-4-501-54970-1/2,835円

を購入。基本的には技術書ではなく読み物(戦記物?)です。ただUnicodeなどの規格の決まり方や海の向こう側の人々の考え方など、なかなか興味深い話です。

2011年6月9日

Windows 7のピン止め機能を無効にする

Windows 7の新機能の一つにタスクバーへのピン止め(pinning、日本マイクロソフトの表現では"固定表示")があります。この機能はタスクバーと従来のクイックリンクを統合したようなもので、ユーザの明示的な操作によりタスクバー上のプログラムをピン止めし、非起動状態と起動状態の区別を考慮することなく扱うことができる、というものです(プログラム側からピン止めを設定することはできない)。しかしプログラムによってはこの機能を使ってほしくないこともあります。そこでプログラム側でピン止め機能を無効化してみます。

MSDNのApplication User Model IDs (AppUserModelIDs) (Windows)Exclusion Lists for Taskbar Pinning and Recent/Frequent ListsによればAppUserModelIDを設定する前にSystem.AppUserModel.PreventPinningプロパティを設定することでピン止めが無効化されます。Windowsプロパティの設定はSHGetPropertyStoreForWindowで行います。ところがこのWindowsプロパティに関係する定義はDelphi 2010で追加されたPropSysユニット、PropKeyユニットには存在するものの、Delphi 2009およびそれ以前のバージョンでは独自に定義する必要があります。またプロパティキーPKEY_AppUserModel_PreventPinningはDelphi 2010でも定義が存在しないため、これも独自に定義します。

uses
  Windows, SysUtils, ShellAPI, ActiveX
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF RTLVersion >= 21.00}
  , PropSys, PropKey
{$IFEND}
{$ENDIF}
;

{$IFDEF CONDITIONALEXPRESSIONS}
{$IF RTLVersion < 21.00}
const
  SID_IPropertyStore = '{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}';

  IID_IPropertyStore: TGUID = SID_IPropertyStore;
  {$EXTERNALSYM IID_IPropertyStore}

type
  { interface IPropertyStore }
  IPropertyStore = interface(IUnknown)
  [SID_IPropertyStore]
    function GetCount(out cProps: DWORD): HRESULT; stdcall;
    function GetAt(iProp: DWORD; out pkey: TPropertyKey): HRESULT; stdcall;
    function GetValue(const key: TPropertyKey; out pv: TPropVariant): HRESULT; stdcall;
    function SetValue(const key: TPropertyKey; const propvar: TPropVariant): HRESULT; stdcall;
    function Commit: HRESULT; stdcall;
  end;
  {$EXTERNALSYM IPropertyStore}

type
  TSHGetPropertyStoreForWindow = function (hwnd: HWND; const riid: TGUID;
                                           var ppv: Pointer): HResult; stdcall;
{$IFEND}
{$ENDIF}

const
  PKEY_AppUserModel_PreventPinning : TPropertyKey = (
    fmtid : '{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}'; pid : 9);
  {$EXTERNALSYM PKEY_AppUserModel_PreventPinning}


function MarkWindowAsUnpinnable(handle: HWND): HRESULT;
var
  pps: IPropertyStore;
  v: TPropVariant;
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF RTLVersion < 21.00}
  hModule: THandle;
  SHGetPropertyStoreForWindow: TSHGetPropertyStoreForWindow;
{$IFEND}
{$ENDIF}
begin

  Result := 0;

  if CheckWin32Version(6,1) = False then
  begin
    Exit;
  end;

{$IFDEF CONDITIONALEXPRESSIONS}
{$IF RTLVersion < 21.00}
  hModule := LoadLibrary(shell32);
  if hModule = 0 then
  begin
    Exit;
  end;

  try
    @SHGetPropertyStoreForWindow := GetProcAddress(hModule,'SHGetPropertyStoreForWindow');
    if Assigned(SHGetPropertyStoreForWindow) = False then
    begin
      Exit;
    end;
{$IFEND}
{$ENDIF}

    Result := SHGetPropertyStoreForWindow(handle,IID_IPropertyStore,Pointer(pps));
    if Succeeded(Result) = True then
    begin
      v.vt := VT_BOOL;
      v.boolVal := True;
      Result := pps.SetValue(PKEY_AppUserModel_PreventPinning,v);
    end;
    pps := nil;

{$IFDEF CONDITIONALEXPRESSIONS}
{$IF RTLVersion < 21.00}
  finally
    FreeLibrary(hModule);
  end;
{$IFEND}
{$ENDIF}

end;
MarkWindowAsUnpinnableはメインフォームのOnCreateイベントハンドラで
procedure TForm1.FormCreate(Sender: TObject);
begin

  MarkWindowAsUnpinnable(Handle);

end;
のように呼び出します。

元ねたはRaymond ChenさんHow do I prevent users from pinning my program to the taskbar? - The Old New Thing - Site Home - MSDN Blogs

2011年6月7日

Delphi Certification Program正式アナウンス

先日お伝えしたDelphi Certification Programが正式にアナウンスされています。

Embarcadero Certification Center

Delphi Certification ProgramはDelphiプログラマの認定試験で、Delphi DeveloperDelphi Master Developerの2つのレベルが用意されています。どちらも60分間で60問出題され、80%(48問)が合格ラインになります。試験は中立の第三者機関が管理します。また認定は合格後2年間有効です。

Delphi Developer Certificationは基本的な知識を問うもので、以下の11の分野から出題されます。
  • Delphiの基礎
  • データ型、変数、定数
  • プロシージャと関数
  • クラスとオブジェクト
  • 標準手続きとI/O
  • ライブラリとパッケージ
  • オブジェクトインタフェース
  • メモリ管理
  • ジェネリクス、属性、無名メソッド
  • 例外とアサーション
  • データベースの概念
受験料は49USDで、オンラインでどこからでも受験することができます。RAD Studio/Delphi XEの登録ユーザは2011/07/31までにコードを取得して90日以内に受験することで無料で試験を受けることができます。

Delphi Master Developer Certificationは高度な知識を問うもので、以下の12の分野から出題されます。
  • Windowsの概念
  • Delphi XEのインタフェースと設定
  • DelphiのVCLとRTL
  • コンポーネントの扱い
  • Delphi言語とオブジェクト指向プログラミング
  • データベースの共通テクニック
  • dbExpress
  • DataSnap
  • DLLとパッケージの記述
  • コンポーネント設計の基本
  • インターネットプログラミング
  • XMLの扱い
受験料は149USDで、エンバカデロのパートナの認定センターが運営します。

FAQも用意されています。

Delphi Certification FAQs

と、ここまで書いておいてなんですが、残念なことに現時点では日本での扱いは決まっていないようです。

元ねたはAndreano LanusseさんDelphi Certification Program – Official Announcement | Andreano Lanusse Blog | Technology and Software Development

2011年5月25日

シリアルポートコンポーネント

シリアルポート(COM/RS-232C)はレガシーではありますが、依然として使用する機会の多いインタフェースです。そこで一般的にお勧めできそうなシリアルポートコンポーネントを探してみました(対応するDelphi/C++Builderのバージョンはあくまで目安です)。

ComPort Library
作者はDejan Crnilaさん、現在のメンテナはLars B. Dybdahlさん、Paul Dolandさん、Brian Gochnauerさんです。Delphi 3/4/5/6/7/8/2005/2006/2007/2009/2010/XE、C++Builder 3/4/5/6に対応しています。最新バージョンは4.11a(2011/05/22)、ライセンスはPublic Domainです。

TurboPower Async Professional
もともとはTurboPower Softwareの商用製品で、オープンソース化されたTurbo Powerプロジェクトの多機能通信コンポーネント群。現在のメンテナはSean B. Durkinさん、tpsfadmin(TurboPower)ことNick Hodgesさんです。Delphi 7/2005/2007/2010に対応しています。最新バージョンは5.0(2010/03/10)、ライセンスはMPL 1.1です。関連: Installing AsyncPro into Delphi XE and C++Builder XE

SynaSer serial library
Ararat s.r.o.SYNAPSE libraryに含まれるシリアル通信コンポーネント。Delphi/C++Builder 3/4/5/6/7/2005/2006に対応しています。最新バージョンはRelease 16/Version 7.2.0(2007/12/21)、ライセンスは修正BSDスタイルです。

TksComPort
Sergey Kasandrovさんによるkstoolsに含まれるシリアル通信コンポーネント。Delphi 2007/2009に対応しています。最新バージョンは0.50(2010/04/30)、ライセンスはMIT Licenseです。

ComPort component
Winsoftによる商用製品(35.00-70.0USD)。Delphi/C++Builder 5/6/7/2005/2006/2007/2009/2010/XEに対応しています。最新バージョンは3.5(2010/12/01)。

nrComm Lib
DeepSoftwareによる商用製品(69.00-599.00EUR)。Delphi/C++Builder 3/4/5/6/7/2005/2006/2007/2009/2010/XEに対応しています。最新バージョンは9.17(2011/05/11)。

お勧めはComPort LibraryかTurboPower Async Professionalでしょうか。シンプルなものがよければ前者、多機能なものがよければ後者、という感じで。

元ねたはTeam Japan » Delphi XE で COMポート(RS-232C)を操作するなど。

2011年5月24日

よりよいQCレポートの書き方

エンバカデロのQualityCentralのSysopの一人であるUwe SchusterさんHow to improve your QC reports?(QCレポートを改善する方法)というアーティクルを書いています。興味深い。

てきとうな要約: まず、最大の誤りは問題をレポートしないことです。なぜならあなたがその問題は修正されると思っていない、ということだからです。
  • Build No
    ここにはRAD Studioのフルバージョン番号を記入する(XE Update 1なら15.0.3953.35171)。これはどのUpdate/Hotfixを適用した状態なのかを知るために重要。
  • Language/Nationality
    ローカライズとは関係のない問題では"US"。表示の欠けや誤訳などのローカライズに関係する問題ではその言語を選択。不必要に言語を指定するとまずローカライゼーションチームに回されるため修正まで時間が掛かるかも。
  • Type and Severity
    この2つの項目は全てのユーザの視点で指定するべきで、高すぎる評価はSysopやQAによって修正されることがある。またコンパイラによる内部エラー("Fxxxx Internal Error")はTypeを(Crash/Data loss/Total failure)とする。
  • Steps
    Stepsには明白であっても予想される動作と実際の動作を記入する。レポートをOpenにするためには再現可能でなければならない。テストケースのないコンパイラの内部エラーは既存のレポートと重複しているものとして扱われ、修正されない可能性が高い(原因が異なっていても同じエラーになるので)。
  • Automated Reports
    IDEがJCLスタックトレース機能を使って生成するものでAIRレポートとも呼ばれ、QCのDelphi.NETに分類される。これは過去の経緯によるものなので、気にせずそのまま(Delphi/C++Builderプロジェクトに変更したりせず)送信する。
  • Voting
    新しいvoteシステムは2007年から使用されており、それぞれのレポートに+/-10の範囲でvote(投票)することができる。webクライアントは新しいvoteシステムに対応しておらずvote値を指定できないので、Win32クライアント(かQC Plus)を使用するのが望ましい。
  • Questions
    QCレポートの扱いについて質問がある場合はForum: QualityCentralへ。


QualityCentralのレポートの書き方に関しては以下のアーティクルも参考になります。

Quality Centralでのバグレポートのコツ
Quality Centralの基礎知識 - Delphi 2009 特集
バグレポートの際のコツ - Delphi 2009 特集
QualityCentral の Tips
Quality Central についての基礎知識

2011年5月19日

Windowsの互換モード上でのLCMapStringの不具合

ちょっと前になりますが、au2010さんのところで気になる話を見つけました。

Windows7でDelphi7のプログラムを動かす時の注意点 - au2010の日記

実際にLCMapString (ja)の動作を確認してみると、Windows 7で互換モードを設定(プログラムのショートカットの"互換性"タブで"互換モード"にチェックオン)すると、LCMapStringのcchDestを0にしたときだけ戻値がA版(LCMapStringA)であっても(W版と同様の)文字数で返ってくる、という不具合があります(cchDestが非0ならば戻値は仕様通り)。いろいろ調べてみましたがプログラム側から互換モードの指定状況を知る方法はなく、結果が既知の変換動作を行わせて、その戻値で判定するしかないようです。ということで半角→全角変換全角→半角変換のコードを修正しました。

2011年5月18日

C++0x FDIS(N3290)解説

C++0xの規格化作業は最終段階に差し掛かっていて、現在はN3290FDIS(Final Draft International Standards)として公開されています(もちろん英語で)。

このC++0xのN3290について、2011/05/14に行われたBoost.勉強会 #5 名古屋道化師さんが解説した資料が見られるようになっています。

C++0x総復習 (Boost.勉強会 #5 名古屋 - boostjp)

slideshareだとこちらですね。

C++0x総復習

江添さんによる本の虫: post-Madrid mailingの簡易レビューも併せて読むといいと思います。

元ねたはアキラさんBoost.勉強会 #5 名古屋でした - Faith and Brave - C++で遊ぼう

Delphiにも"= delete"(§8.4.3 Deleted definitions)があればこんなことをしなくてもすんだのに…。

2011年5月17日

DelphiでSingletonパターンを実装する(リベンジ)

DelphiでSingletonパターンを実装する(再考)ではTSingletonのインスタンスの解放を防ぐためにデストラクタ内で例外を送出する、という方法を考えてみましたが、2ちゃんねる界隈では不評だったようです。一般論からいえば確かにデストラクタからの例外の送出はいかがなものか、という気もしますが、そもそもこのアプローチは(コンストラクタからの例外の送出による複数インスタンスの生成の防止と同様に)テストレベルで問題コードを検出、修正するためのものであって、リリースコード上で実行されることを想定しているわけではありません。また前回考察したように、一旦呼び出しがなされたコンストラクタ、デストラクタのインスタンスに対する生成、破棄処理を回避するには例外の送出しかないことも確かです。ということで"より望ましい"解決方法を考えてみることにします。

まず前回の"Phoenix Singleton"ですが、デストラクタを呼び出すことでインスタンスが完全に解放されてしまうため、次回のアクセスで新しいインスタンスが生成されてもその内容は初期状態に戻ってしまいます。そこで"予備"のインスタンスを用意しておき、ここに内容を退避して再生成時に復元します。まずinitialization/finalization版から。
unit Unit32;

interface

uses
  SysUtils;

type
  TSingleton = class(TObject)
  private
    FTestValue: Integer;
    constructor CreateInstance;
  public
    constructor Create;
    destructor  Destroy; override;
    procedure   Assign(Source: TSingleton);
    class function GetInstance: TSingleton;
    property    TestValue: Integer
                  read  FTestValue
                  write FTestValue;
  end;

  ECreateSingleton = class(Exception)
  end;


implementation

var
  FSingleton: TSingleton;
  FShadowSingleton: 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

  { Shadowing }
  if FShadowSingleton = nil then
  begin
    FShadowSingleton := TSingleton.CreateInstance;
  end;
  if FShadowSingleton <> Self then
  begin
    FShadowSingleton.Assign(Self);

    { Delete singleton reference }
    FSingleton := nil;
  end;

  { Finalize }

  inherited;

end;

procedure TSingleton.Assign(Source: TSingleton);
begin

  { Copy from source }
  TestValue := Source.TestValue;

end;

class function TSingleton.GetInstance: TSingleton;
begin

  if FSingleton = nil then
  begin
    FSingleton := TSingleton.CreateInstance;
    if FShadowSingleton <> nil then
    begin
      FSingleton.Assign(FShadowSingleton);
    end;
  end;

  Result := FSingleton;

end;

initialization
  FSingleton := nil;
  FShadowSingleton := nil;

finalization
  FSingleton.Free;
  FShadowSingleton.Free;

end.
次にclass constructor/class destructor版です。
unit Unit34;

interface

uses
  SysUtils;

type
  TSingleton = class(TObject)
  private
    FTestValue: Integer;
    class var
      FSingleton: TSingleton;
      FShadowSingleton: TSingleton;
    constructor CreateInstance;
  public
    class constructor Create;
    class destructor  Destroy;
    constructor Create;
    destructor  Destroy; override;
    procedure   Assign(Source: TSingleton);
    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;
  FShadowSingleton := nil;

end;

class destructor TSingleton.Destroy;
begin

  FSingleton.Free;
  FShadowSingleton.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

  { Shadowing }
  if FShadowSingleton = nil then
  begin
    FShadowSingleton := TSingleton.CreateInstance;
  end;
  if FShadowSingleton <> Self then
  begin
    FShadowSingleton.Assign(Self);

    { Delete singleton reference }
    FSingleton := nil;
  end;

  { Finalize }

  inherited;

end;

procedure TSingleton.Assign(Source: TSingleton);
begin

  { Copy from source }
  TestValue := Source.TestValue;

end;

class function TSingleton.GetInstance: TSingleton;
begin

  if FSingleton = nil then
  begin
    FSingleton := TSingleton.CreateInstance;
    if FShadowSingleton <> nil then
    begin
      FSingleton.Assign(FShadowSingleton);
    end;
  end;

  Result := FSingleton;

end;

end.
いずれもシングルトンの内容の退避、復帰のためにインスタンスの内容をコピーするprocedure Assignというメソッドを用意し、これをコンストラクタ、デストラクタで使用します。なおシングルトンが別のクラスのインスタンスを所有するような場合、Assignはいわゆる"deep copy"の動作を実装する必要があります。またpublicなconstructor Createについてはとりあえず従来どおりの例外送出のままとしてあります。

次にコンストラクタ、デストラクタでの例外の送出、というアプローチですが、これは前述のとおりテストレベルでの問題コードの検出、修正を目的としています。しかしこの方法には問題コードが実行されない限り意味をもたない(コンパイル時には検出できない)、という欠点もあります。そこで例外の送出ではなく、constructor Create、destructor Destory、そして再定義したprocedure Freeに(少々目的は異なるものの)ヒント指令deprecatedを指定しておき、これらを呼び出しているコードをコンパイル時に警告されるようにする、という解決策を考えてみます。まずinitialization/finalization版から。
unit Unit28;

interface

uses
  SysUtils;

type
  TSingleton = class(TObject)
  private
    FTestValue: Integer;
    constructor CreateInstance;
    destructor  DestroyInstance;
  public
    constructor Create;            deprecated {$IFDEF CONDITIONALEXPRESSIONS}{$IF CompilerVersion >= 20.00} 'Do not use TSingleton.Create.'  {$IFEND}{$ENDIF};
    destructor  Destroy; override; deprecated {$IFDEF CONDITIONALEXPRESSIONS}{$IF CompilerVersion >= 20.00} 'Do not use TSingleton.Destory.' {$IFEND}{$ENDIF};
    procedure   Free;              deprecated {$IFDEF CONDITIONALEXPRESSIONS}{$IF CompilerVersion >= 20.00} 'Do not use TSingleton.Free.'    {$IFEND}{$ENDIF};
    class function GetInstance: TSingleton;
    property    TestValue: Integer
                  read  FTestValue
                  write FTestValue;
  end;


implementation

var
  FSingleton: TSingleton;

{ TSingleton }

constructor TSingleton.Create;
begin

  { Place holder, do not use }

end;

destructor TSingleton.Destroy;
begin

  { Place holder, do not use }

end;

constructor TSingleton.CreateInstance;
begin

  inherited Create;

  { Initialize }
  FTestValue := 0;

end;

destructor TSingleton.DestroyInstance;
begin

  { Finalize }

  inherited Destroy;

end;

procedure TSingleton.Free;
begin

  { Place holder, do not use }

end;

class function TSingleton.GetInstance: TSingleton;
begin

  if FSingleton = nil then
  begin
    FSingleton := TSingleton.CreateInstance;
  end;

  Result := FSingleton;

end;

initialization
  FSingleton := nil;

finalization
  if FSingleton <> nil then
  begin
    FSingleton.DestroyInstance;
  end;

end.
Delphi 2009以降({$IFDEF CONDITIONALEXPRESSIONS}{$IF CompilerVersion >= 20.00}で判定)ではdeprecatedに追加のメッセージを指定しています。

次にclass constructor/class destructor版です。
unit Unit30;

interface

uses
  SysUtils;

type
  TSingleton = class(TObject)
  private
    FTestValue: Integer;
    class var
      FSingleton: TSingleton;
    constructor CreateInstance;
    destructor  DestroyInstance;
  public
    class constructor Create;
    class destructor  Destroy;
    constructor Create;            deprecated 'Do not use TSingleton.Create.';
    destructor  Destroy; override; deprecated 'Do not use TSingleton.Destory.';
    procedure   Free;              deprecated 'Do not use TSingleton.Free.';
    class function GetInstance: TSingleton;
    property    TestValue: Integer
                  read  FTestValue
                  write FTestValue;
  end;


implementation

{ TSingleton }

class constructor TSingleton.Create;
begin

  FSingleton := nil;

end;

class destructor TSingleton.Destroy;
begin

  if FSingleton <> nil then
  begin
    FSingleton.DestroyInstance;
  end;

end;

constructor TSingleton.Create;
begin

  { Place holder, do not use }

end;

destructor TSingleton.Destroy;
begin

  { Place holder, do not use }

end;

constructor TSingleton.CreateInstance;
begin

  inherited Create;

  { Initialize }
  FTestValue := 0;

end;

destructor TSingleton.DestroyInstance;
begin

  { Finalize }

  inherited Destroy;

end;

procedure TSingleton.Free;
begin

  { Place holder, do not use }

end;

class function TSingleton.GetInstance: TSingleton;
begin

  if FSingleton = nil then
  begin
    FSingleton := TSingleton.CreateInstance;
  end;

  Result := FSingleton;

end;

end.
どちらもDelphi 2009以降であれば"プロジェクトオプション"の"Delphiコンパイラ"の"ヒントと警告"で"使用を推奨されていないシンボル"をエラーにするか、シングルトンを使用している側のユニットに
{$WARN SYMBOL_DEPRECATED ERROR}
を指定することでconstructor Create、destructor Destory、procedure Freeの呼び出しをエラーにすることができます(通常は警告)。

2011年5月16日

IDE Fix Pack 4.1/DelphiSpeedUp 3.1リリース

Andreas HausladenさんIDE Fix Pack 2007およびIDE Fix Pack 2009/2010/XEがアップデートされてVersion 4.1に、DelphiSpeedUpもDelphi 7/2007用がアップデートされてVersion 3.1になっています。IDE Fix Pack、DelphiSpeedUpともRCからの変更はないようです。

IDE Fix Pack 4.1, DelphiSpeedUp 3.1 | Andy’s Blog and Tools

2011年5月11日

Microsoft Monthly Update 2011/05

今日はMicrosoftのセキュリティアップデートの日です。
MS11-035
MS11-036

2011年5月9日

コンストラクタとデストラクタについての考察

Delphiのコンストラクタ、デストラクタとは、ヘルプの

コンストラクタ (メソッド)
デストラクタ (メソッド)

にあるように、クラスのインスタンスを生成、破棄するための特別なメソッドです。あまり知られていませんがコンストラクタとデストラクタには

メソッド呼び出しの処理 (プログラムの制御)

にあるように、Pointer型とByte型の2つの隠しパラメータが存在します(デフォルトのregister呼出規約ではEAXレジスタとDLレジスタ)。第1パラメータ(Pointer型)はSelf(C++のthisに相当)です。一方で第2パラメータ(Byte型)は真偽値(0または非0)であり、クラスメソッドとして呼び出される場合、つまり
  Foo := TFoo.Create;
では1(真)が設定され、インスタンスメソッドとして呼び出される場合、つまり
constructor TFoo.Create;
begin
  inherited;
end;
のinherited(継承元コンストラクタの呼び出し)では0(偽)が設定されます。コンストラクタでは先頭にこの第2パラメータをチェックして真の場合はインスタンス領域の確保と初期化が行われるようなコードが生成されます(確保したインスタンス領域のアドレスはEAXに格納され、呼出元に返されます)。またデストラクタでは末尾に第2パラメータのチェックとインスタンス領域の解放が行われるようなコードが生成されます。さらにコンストラクタでは内部で例外が生成されたときに自動的にデストラクタが呼び出され、初期化後に変更されたフィールドに対してリソースの解放を行うことでコンストラクタで例外を送出したときのリソースリークを防ぐような仕組みになっています。

実際のコードで確認してみましょう(例はシングルトンパターンその1のUnit2をDelphi 2007でデバッグビルドしたものです)。

コンストラクタ呼び出し
  FSingleton := TSingleton.Create;


Unit2.pas.30: FSingleton := TSingleton.Create;
00457C35 B201             mov dl,$01
00457C37 A1D47B4500       mov eax,[$00457bd4]
00457C3C E80B000000       call TSingleton.Create
00457C41 A3CC0C4600       mov [$00460ccc],eax

となり、DLレジスタに0x01が設定されてコンストラクタ(TSingleton.Create)を呼び出しています。コンストラクタ本体の
constructor TSingleton.Create;
begin

  inherited;

  { Initialize }
  FTestValue := 0;

end;


Unit2.pas.38: begin
00457C4C 53               push ebx
00457C4D 56               push esi
00457C4E 84D2             test dl,dl
00457C50 7408             jz $00457c5a
00457C52 83C4F0           add esp,-$10
00457C55 E8B2C0FAFF       call @ClassCreate
00457C5A 8BDA             mov ebx,edx
00457C5C 8BF0             mov esi,eax
Unit2.pas.40: inherited;
00457C5E 33D2             xor edx,edx
00457C60 8BC6             mov eax,esi
00457C62 E869BDFAFF       call TObject.Create
Unit2.pas.43: FTestValue := 0;
00457C67 33C0             xor eax,eax
00457C69 894604           mov [esi+$04],eax
Unit2.pas.45: end;
00457C6C 8BC6             mov eax,esi
00457C6E 84DB             test bl,bl
00457C70 740F             jz $00457c81
00457C72 E8EDC0FAFF       call @AfterConstruction
00457C77 648F0500000000   pop dword ptr fs:[$00000000]
00457C7E 83C40C           add esp,$0c
00457C81 8BC6             mov eax,esi
00457C83 5E               pop esi
00457C84 5B               pop ebx
00457C85 C3               ret

と先頭でDLレジスタが非0ならばClassCreateを呼び出し、BLレジスタにDLレジスタの値を保存してからDLレジスタを0に変更して以下の処理を行い、最後にBLレジスタ(=呼び出されたときのDLレジスタ)が非0であればAfterConstructionを呼び出すようになっています。

次にデストラクタを見てみます。といってもサンプルではTObject.Freeで呼び出しが隠蔽されてしまっていますので、ここはDestroyを直接呼び出すようにしてみます。
  FSingleton.Destroy;


Unit2.pas.63: FSingleton.Destroy;
00457CD2 B201             mov dl,$01
00457CD4 A1CC0C4600       mov eax,[$00460ccc]
00457CD9 8B08             mov ecx,[eax]
00457CDB FF51FC           call dword ptr [ecx-$04]

となり、やはりDLレジスタに0x01を格納してからデストラクタを呼び出しています(呼出先が[ecx-$04]というのはVMT経由でデストラクタのアドレスを取得しているためです)。デストラクタ本体の
destructor TSingleton.Destroy;
begin

  { Finalize }

  inherited;

end;


Unit2.pas.48: begin
00457C88 53               push ebx
00457C89 56               push esi
00457C8A E825C1FAFF       call @BeforeDestruction
00457C8F 8BDA             mov ebx,edx
00457C91 8BF0             mov esi,eax
Unit2.pas.52: inherited;
00457C93 8BD3             mov edx,ebx
00457C95 80E2FC           and dl,$fc
00457C98 8BC6             mov eax,esi
00457C9A E851BDFAFF       call TObject.Destroy
Unit2.pas.54: end;
00457C9F 84DB             test bl,bl
00457CA1 7E07             jle $00457caa
00457CA3 8BC6             mov eax,esi
00457CA5 E8B2C0FAFF       call @ClassDestroy
00457CAA 5E               pop esi
00457CAB 5B               pop ebx
00457CAC C3               ret

となり、まずBeforeDestructionが呼び出され、BLレジスタにDLレジスタの値を保存してから0xFCとANDをとって(DLレジスタは0x01 AND 0xFC = 0x00となっている)継承元デストラクタを呼び出し、最後にBLレジスタ(呼び出されたときのDLレジスタ)が非0であればClassDestroyを呼び出すようになっています。またデストラクタ内でExitしても

Unit2.pas.48: begin
00457C88 53               push ebx
00457C89 56               push esi
00457C8A E825C1FAFF       call @BeforeDestruction
00457C8F 8BDA             mov ebx,edx
00457C91 8BF0             mov esi,eax
Unit2.pas.50: Exit;
00457C93 EB0C             jmp $00457ca1
Unit2.pas.54: inherited;
00457C95 8BD3             mov edx,ebx
00457C97 80E2FC           and dl,$fc
00457C9A 8BC6             mov eax,esi
00457C9C E84FBDFAFF       call TObject.Destroy
Unit2.pas.56: end;
00457CA1 84DB             test bl,bl
00457CA3 7E07             jle $00457cac
00457CA5 8BC6             mov eax,esi
00457CA7 E8B0C0FAFF       call @ClassDestroy
00457CAC 5E               pop esi
00457CAD 5B               pop ebx
00457CAE C3               ret

とBLレジスタのチェックにジャンプするようになっており、DLが非0の呼び出しでは途中でExitしても必ずClassDestroyが呼び出されます。

このような事情から、コンストラクタの呼び出しによるクラスインスタンスの生成をキャンセルするためにはコンストラクタ内で例外を送出し、最外側コンストラクタ先頭で確保したインスタンス領域をデストラクタで解放させるしかありません(コンストラクタをクラスメソッドで呼び出すと必ず領域確保が行われるため)。同様にデストラクタの呼び出しによるインスタンスの破棄をキャンセルするには最外側のデストラクタの末尾までのどこかの時点で必ず例外を送出してインスタンス領域の解放を防ぐ必要があります。

元ねたはDelphiクイックリファレンス (amazon)/Ray Lischner著/光田秀、竹田知生訳/オライリー・ジャパン/ISBN4-87311-040-8/4,725円。

2011年5月2日

MS11-025によって発生する問題とその対策

2011/04のセキュリティアップデートのうち、MS11-025には、
  1. Windows 2000 SP4にKB2467175 (Visual C++ 2005 SP1 再頒布可能パッケージ セキュリティ更新プログラム (2011 年 4 月 12 日))およびKB2467174 (Visual C++ 2008 SP1 再頒布可能パッケージ セキュリティ更新プログラム (2011 年 4 月 12 日))を適用するとMFC 8.0/9.0を動的にリンクしているプログラムが起動時にエラーになる。
  2. VC2008でMFCを静的リンクしたプログラムのサイズが(VC2010と同様に)不必要に大きくなる。
  3. MFC 8.0/9.0を動的にリンクしているプログラムがMFCの言語DLLを使用しない(DLLを発見できなくなる)。
  4. Windows XP以降にしか存在しないFindActCtxSectionStringAに静的にリンクしてしまうためリビルドしたプログラムがWindows 2000で動作しなくなる。
といった問題が存在しているようです。

このうちWindows 2000とVC2005/VC2008再頒布可能パッケージ(Redist)の問題についてはKB2467175とKB2467174がWindows 2000の適用範囲外となったため、インストールしないのが正しく、もしインストールしてしまった場合は

New redists break all dynamically linked MFC 2005/2008 apps on Windows 2000 « Ted's Blog

にあるように、
  1. KB2467175とKB2467174をアンインストール
  2. Windows(WINNT)フォルダ内のWinSxSフォルダから4053と4148を検索して(フォルダが存在しなければ代わりにそれぞれ762と21022で検索)、検索結果に含まれるフォルダ内のファイル(ATLxx.DLL, MFCxx*.DLL, MFCMxx*.DLL, MSVCMxx*.DLL, MSVCPxx*.DLL, MSVCRxx*.DLL, VCOMPxx.DLL)全てを一時フォルダ("C:\MFCDLL"など)にコピー
  3. Windowsを再起動
  4. [F8]キーを押してWindows 2000拡張オプションメニューを表示し、セーフモードとコマンドプロンプトでコマンドプロンプトを選択して起動
  5. 一時フォルダ内のファイルをSystem32に
    copy C:\MFCDLL\*.* C:\Windows\System32
    (一時フォルダが"C:\MFCDLL"でWindowsのインストールフォルダが"C:\Windows"の場合)
    としてコピー
  6. EXITで再起動
という手順で回復することができます。

その他の(Visual Studio上での開発に関する)問題とその解決方法については

Problem with FindActCtxSectionString in MFC security updates on all platforms « Ted's Blog
Martin's Blog » BUG: Black Patchday for all OS from XP and later 3. – MFC 8.0 (VC-2005) or MFC 9.0 (VC-2008) linked dynamically to the MFC may not find the MFC language DLLs after installation of the security packs dated April 12th 2011
Static MFC code bloat problem from VC2010 is now in VC2008 SP1+security fix « Ted's Blog
Fixing problems with FindActCtxSectionString in MFC security updates « Ted's Blog

が参考になります。

2011/05/05追記: MicrosoftのVisual C++ Team Blogにもこの件に関する記事があります(考えてみれば当たり前か)。

MS11-025 Visual C++ Update Issue - Visual C++ Team Blog - Site Home - MSDN Blogs

これによると、Windows 2000に関する問題についてはこの時点(2011/04/26)ではMS11-025をアンインストールするしかないようですが、
Our team has identified the cause of these issues and is currently testing the fix. The update will be publicly available once testing is complete, and we will update this blog.

いい加減な訳: 我々VC++チームではこれらの問題の原因を特定し、修正したものを現在テストしているところです。テストが完了したらアップデートは一般に利用可能となり、このブログを更新します。

ということで、近日中に何らかの解決が図られるようです。

2011/06/15追記: MS11-025が更新され、以下の問題が解決したとされています。
  • ローカライズされたアプリケーションをご使用のお客様に MFC アプリケーションのリソースの一部がローカライズされずに表示されます。アプリケーションは正常に機能しますが、リソースが英語で表示されます。
  • MFC のセキュリティの修正は Microsoft Windows 2000 でサポートされていない API を使用します。Microsoft Windows 2000 システムに更新プログラムを適用した場合、インストールによっていくつかのアプリケーションの機能的な問題が引き起こされました。
  • 以前の更新プログラムは x64-based アーキテクチャの Windows 7 SDK を使用しているユーザーにはインストールされませんでした。


2011/06/21追記: Visual C++ Team Blogにも新しい更新プログラムで上記の問題を修正した、という記事が出ています。

Update on Bulletin MS11-025 - Visual C++ Team Blog - Site Home - MSDN Blogs