Silverlight 4 と .NET Framework 4 のアセンブリ共有について

エントリを書くのも久し振りなんですが、Silverlight 4ベータが公開されてから .NET Framework 4 とのアセンブリの共有ができるという情報が公開されています。このSilverlightとの共有に関して、情報を整理しようと考えています。詳細は、CLRチームのエントリに記載されていますが、そこに記載されている4つのアセンブリが以下になります。 mscorlib.dll(System 名前空間) System.dll(System.Net 名前空間など) System.Core.dll(System 名前空間で、LINQやDLRなど) Microsoft.VisualBasic.dll(Microsoft.VisualBasic 名前空間で VBで使用するMyや関数などが含まれます) 上記のアセンブリに含まれているライブラリを使用しているプログラムであれば、CoreCLR とデスクトップ CLR がバイナリレベルで実行が可能になることをアセンブリの共有と呼んでいます。アセンブリの共有で実現できることは、以下のポータビリティです。 バイナリレベルでの互換性 ライブラリの互換性 先にご紹介した CLR チームのエントリでは、.NET Framework 4対応の WPF アプリとSilverlight 用のライブラリプロジェクトで動作するという具体例を紹介しています。が、裏側で何が行われているかを推論してみたいと考えています。私は、この動作は以下のようなことを行っていると考えています。 CoreCLR のアセンブリローダーのバインディング ポリシーの設定 デスクトップ CLR のアセンブリローダーのバインディング ポリシーの設定 たとえばデスクトップ CLR 用の mscorlib.dll は約4.83MBあります。これに対して Silverlight のランタイム サイズの目標は2MBになっています(Silverlight 3では約3MBで、mscorlibは約1.4MBです)。このサイズが最終的にデスクトップと同じになるとは、考えられません。というか、MacOS に .NET Framework 4 が提供されませんので、Silverlight 用とデスクトップ CLR 用に別々のライブラリが用意されるのが当たり前と考えることができるからです。このように考えていくと、一部のクラスなどでデスクトップ CLR と…

0

WPF4 ベータ2でのタッチアプリケーションについて

Visual Studio 2010 ベータ2に含まれているWPF 4でマルチタッチのアプリを作ろうとして、ベータ1との違いを調べていました。ローカルドキュメントには含まれていませんが、MSDNライブラリにウォークスルーが公開されています。 一番大きく変わったのが、FrameworkElementに記述していた「ManipulationMode=”All”」が無くなって、「IsManipulationEnabled=”True”」に変更になったことです。この変更に伴って、「ManipulationStartingイベント」でManipulationContainerを設定する必要があります。ManipulationModeは、ManipulationStartingEventArgs.Modeプロパティで設定するようになっています。この値のデフォルトが「All」になっています。 そしてウォークスルーでは、InertiaStartingのイベントハンドラでTranslationBehavior、ExpansionBehavior、RotationBehaiviorを設定しています。このBehaiviorに、移動量を設定しています。また、ManipulationDeltaイベントハンドラの最後にあるif文である「if (e.IsInertial && !containingRect.Contains(shapeBounds))」で境界を越えた時点で動作を終了するようになっています。この境界における制御なのですが、InertiaProcessorの場合はボーダーとエラスティック・マージンという考え方があるのですが、この考え方の適用方法はまだ調べきれていません。 これ以外には、WM_Touchイベントも処理できるようになっています。

0

Visual Studio 2010 日本語版ベータ2 のインストールについて

MSDN会員向けに Visual Stduio 2010 ベータ2 日本語版が公開されました。英語版のベータ2から入れ替える場合の注意点を以下に記載します。 Visual Studio 2010 Beta2 English のアンインストール Visual Studio 2010 Tools for Office Runtime Beta2 のアンインストール Microsoft .NET Framework 4 Extended Beta2のアンインストール Microsoft .NET Framework 4 Client Profile Beta2のアンインストール Microsoft Visual C++ Redistributable – x86 9.0.30729.4148のアンインストール をしてからインストールします。気がついた注意点としては、Visual Studio 2010 Beta2のアンインストールが終了してからも、しばらくはsetup.exeが動き続けている点です。しばらく待てば、setuo.exeが終了しますので、それ以降のアンインストールを行うことができます。 また、日本語版ベータ2には、機械翻訳のドキュメントが付属しています。 Visual Studio 2010ベータ1のアンインストールは、ダウンロードページにある Instruction欄にあるHereからインストールに関するReadmeをダウンロードできますので、この手順に従った方が良いようです。簡単に手順を記載すると以下のようになります。 Microsoft Team Foundation Server 2010…

4

TechEd 2009 での Silverlight3 を使ったピアノサンプルについて

TechEd 2009のMVPラウンジでお見せしたSilverlight 3のマルチタッチ対応のピアノのデモですが、その後の調査で作成したデモのバグのためにSilverlight3ランタイムがハングアップしたようになっていたことが判明しました。この件は、多くの方が陥りそうな気がするので自戒の意味も込めて、状況を以下に記載します。 Silverlight3でマルチタッチを使用するには、System.Windows.Input.Touchクラスを使用します。 具体的には、「Touch.FrameReported += Touch_FrameReported」のようにイベントハンドラを登録します。イベントハンドラは、「void Touch_FrameReported(object sebder, TouchFrameEventArgs e)」というシグネチャを持ちます。 イベントハンドラ内では、タッチポイントコレクションを取得します。 「TouchPointCollection touchPoints e.GetTouchPoints(FrameworkElement)」メソッドでタッチポイントコレクションを取得します。タッチポイントコレクションには、複数のタッチされたポイントで構成されています。 タッチポイントコレクションからタッチポイントを取り出して処理します。 「foreach (TouchPoint tp in touchPoints)」のようにタッチポイントを列挙します。タッチポイントには、ActionプロパティとTouchDeviceプロパティなどがあります。 Actionプロパティによってタッチ動作を識別します。 TouchAction.Down、Move、Upという列挙値とActionプロパティを比較することでタッチ動作を記述します。タッチの動作の基本は、ダウン->移動->アップ(移動が無い場合もあります)になります。 TouchDeviceプロパティによって、タッチされた場所を識別します。 TouchDevice.Idにタッチした場所の識別子が格納されています。つまり、ダウン->移動->アップが一回のタッチ動作であれば同じ識別子になります。複数(マルチ)のタッチであれば、TouchDevice.Idが異なるので一致するId毎にActionプロパティと組み合わせてタッチ動作を記述します。言い換えると、タッチ動作がダウン->移動->アップですからダウン時にTouchDevice.Idと座標を記録して、移動やアップ時に記録されたIdを取り出してタッチ動作にするのです。 私のサンプルで問題があった個所は、MouseLeftButtonDownイベントとタッチイベントの両方をハンドリングしていたことでした。これで何が問題になったかというと、軽いタッチの場合はOSというかブラウザがタッチダウンをMouseLeftButtonDownイベントに変換してしまうので、タッチダウンイベントを処理できないというものでした。  if tp.Action == TouchAction.Down) { Path hitKey = null; // タッチされた場所の最上位のFrameworkElementを取得 FrameworkElement hitElement = tp.TouchDevice.DirectOver as FrameworkElement; // これが対処したコード while (hitElement != null) { if (hitElement is Path) {…

0

Windows Touch について

Windows 7もRTMしまして、マルチタッチに対応しているPCが幾つかあります。具体的には、以下のようなPCです。 HP Touch Smart IQ800 や IQ500 HP Touch Smart tx2 ノートブック DELL Latitude XT2 や XT Microsoftで行うデモで良く見かけるのが、IQ800です。個人で所有するとなると、ノートブックになると思います。このように記述している私もHP Touch Smart tx2を購入しました。現在は、Windows 7 RTMをインストールして、マルチタッチ対応のプログラムを開発するのに使っています。マルチタッチ対応のプログラムの実行環境としては、以下のような方法があります。 Silverlight 3 .NET Framework 3.5 WPF4(.NET Framework 4.0ベータ1) Win32 APIを使ったネイティブアプリケーション Silverlight 3で開発するには、System.Windows.Input.Touchクラスを使用します。.NET Framework 3.5(WPFかWindows Forms)の場合は、Windows 7 Multitouch .NET Interop Sample Libraryを使用するのが簡単です。このライブラリの場合は、Win32 APIをラップしたヘルパークラスが提供されています。WPF4では、FrameworkElementにTouchイベントハンドラを記述できるようになっています。が、IDEで自動的には記述できませんのでXAMLに記述する必要があります。 Windows Touchを理解するには、ManipulationとInertiaを理解するのが良いでしょう。WM_GESTUREやWM_TOUCHメッセージは低レベルなものなので、自分で動作を作りこむ必要があります。これに対して、ManipulationやInertiaでは、複数のタッチによる振る舞いを処理するための仕組みが用意されているからです。デモなどで見かける、写真の移動や回転、ズームなどがManipulationで実現されているのです。 Silverlight3のWindows Touch対応は、WM_TOUCHメッセージのみの対応となります。従って、タッチによる振る舞いは、コードで作りこむ必要があります。 HP Touch Smart tx2を使っていて気がついた点は、マルチタッチのドライバーの動作が不安定だということです。色々と調べていくと、ACアダプタを抜いてバッテリモードで試すと安定していることに気がつきました。私が使用しているマルチタッチのドライバーでは、静電式パネルのタッチポイントの認識時に電源周りの磁界が影響するようです。この点を気をつけるようになってから、安定してマルチタッチを試すことができるようになりました。

0

Deep Dive to .NET Framework CLR を作成中です

TechEd 2009 横浜で「Deep Dive to .NET Framework CLR」というセッションを担当します。この資料を作成しています。このセッションは、私の著書である「The Root of .NET Framework」という書籍をモチーフにして、資料を構成しています。どのような内容が良いか、悩みながら作成を行っています。その途中経過を以下に引用します。 PEヘッダーから CLIヘッダーのアドレスを見つけて   CLI ヘッダーを読み解くのが、上記のスライドです。ここまで来るとメタデータが、どのように格納されているかを知りたくなることでしょう。それらも作成しているのですが、どこまで作るかが難しいところです。 これ以外にも、GCやCLRのホストインターフェース、RCWなどとアイディアがあるのですが、如何とも時間の制約がありますので作成したスライドを全部、説明しきれないかもしれません。現時点で30スライド程度が出来上がっていて、ここから SOSデバッガ拡張や.NET Framework 4.0の話を入れようと思っていますので。まだまだ、悩みは尽きません。公開されているセッションレベルは400番台なので、最低でも16進数ダンプの見方を知っている方が対象になると思います。

0

DLR の COM バインダーに対する考察

DLRを使ったExcelプログラミングというエントリーで、興味深いご指摘をいただきました。それは、COMオブジェクトのリリースを誰が面倒を見てくれるのかというものです。この問題を考える上で意識しないといけないのが、オブジェクトのライフサイクルの管理という側面です。具体的には、以下のようなものです。 マネージ オブジェクトは、GCによって回収される。 COM オブジェクトは、COMサーバーが参照カウンタが0になった時点で消滅させる。 オブジェクトの生存の可否そのものが、異なる観点で管理されているのです。つまり、 マネージ オブジェクトは、マネージヒープ上で参照されないものがGCによって回収される。つまり、ルート オブジェクトから辿っていけないオブジェクトが、回収の対象になる。 COMは参照カウンタで管理していおり、マネージコードからはRCWが内部で参照カウンタに対する操作を行う。従って、RCWが回収されない限り参照カウンタがデクリメントされない。 ということです。COM参照をカウンタを適切なタイミングでデクリメントするには、Marshal.ReleaseComObjectメソッドを呼ぶ必要があります。(注)GCはCLRホスト内に存在しますので、アプリケーションがアンロードされれば解放されます。アンロード前にCOMサーバーを解放するために、Marchal.ReleaseComObjectを呼ぶかGC.Collectを呼び出す必要があるだけです。この考えをベースに.NET Framework 4.0で導入されるDLRについて考えていきます。C#言語では、dynamicというキーワードによってレイトバインディングが実現されます。dynamicというキーワードを付与した変数は、コンパイルされたILを見るとSystem.Object型がSystem.Runtime.CompilerServices.DynamicAttributeによって振る舞いを変えるようになっています。この振る舞いを変えるという言葉の意味は、以下のようなことを意味しています。 通常のメソッド呼び出し:IL上は、直接メソッドを呼び出す(MethodInfoを示すマネージポインタである)。 dynamic属性を持つオブジェクトのメソッド呼び出し:名前によってMethodInfoを取得してから、Invokeで呼び出す(この意味で、リフレクションを使ってMethodInfoを取得してからInvokeするのと同じです。厳密には、DLRのバインダーによってこれらの処理が行われます)。 つまりdynamicというキーワードは、リフレクションを使ってメソッドを呼び出す代わりにDLRが実行時にメソッド名の文字列からメソッドを呼び出してくれることになります。この時のパラメータの型に応じた呼び出しを最適化するために、CallSiteキャッシングという仕組みをDLRは用意しているのです。CallSiteキャッシングによって、同じパラメータを使ったメソッド呼び出しが高速化されるというメリットがあります。つまり実行時に文字列でメンバーを解決するが、繰り返し呼び出す場合の高速化メカニズムが用意されているのがDLRというレイトバインディングになります。今までのメソッド呼び出し比較した場合に、コンパイラが解決するか、実行時に解決するかという違いから速度的にdynamicの方が不利になるケースもあることでしょう。ですが、それは初回のメソッド呼び出し時のオーバーヘッドの違いで、2回目以降は同じとは言いませんが遜色ない程度に早くなると言えるでしょう。 これらの動的なメンバー呼び出しをCOMオブジェクトに適用するのが、DLRのCOMバインダーの役割になります。COMバインダーの設計思想は、VB6.0と同じようにCOMのAutomationインタフェースを使えるようにすることにあります。このため名前を使ってIDispatch::GetIDsOfNameメソッドでDispIDを取得してから、IDispatch::Invokeを呼び出すメカニズムを提供します。このことは、CLRにのCOMインタロップの仕組みとは異なっています。COMインタロップでは、インタロップ・アセンブリ(TLBから生成-tlbimp.exe-)を生成してアーリーバインディングを実現します。もちろん、自分でコードを記述するかVBコンパイラを使うことで、レイトバインディングを実現することもできました。これらのレイトバインディングが、コードを記述することなくCOMのAutomationインターフェース経由でCOMを扱えるようになるのが、DLRのCOMバインダーです。 ここまででdynamicキーワードでCOMを扱う時の特徴が理解できたのではないでしょうか。具体的には、以下のようなことです。 COMオブジェクトのインスタンスは、RCWでラップされている。参照カウンタは、RCWが管理している。 メンバー呼び出しは、COMバインダーがGetIDsOfName、Invokeを使って呼び出している。 そうするとCOMオブジェクトのインスタンスを早期に回収するには、プログラマがコードを記述する必要があるということです。この意味において、今までと何も変わらないということができます。異なるのは、メンバーを呼び出す内部の仕組みだけです。 但し、.NET Framework 4.0ベータ1では実装されていませんが、DLR-0.91のソースコードに含まれるMicrosoft.Scripting.ComRuntimeHelpers.IUnknownReleaseDelegate(Microsoft.Dynamicの中にあります)のコメントなど参照してみてください。この実装などが、DLRの最終形に入ってくればDLRのCOMバインダーでCOMオブジェクトのリリースまで管理してくれる可能性があります。まだ開発途中ですので、DLRの開発方向を調べたい場合はcodeplexのDLRを参照するようにしてください。 PS.DLRのCOMバインダーは、System.Dynamic.dllアセンブリに実装されています。

5

書籍紹介: C# .NET アプリケーション開発 徹底攻略

毎日コミュニケーション 山口様より、献本していただきました。 タイトル:C# .NET アプリケーション 徹底攻略作者:伊藤 真二発売日:2009/4/23メディア:単行本(ソフトカバー) 経験値をあげて高品質な業務アプリを作ろう 内容は、以下のような構成になっています。 導入 .NET Frameworkアプリケーション設計 チューニング リリース管理/セキュリティ COMアプリケーション連携 新しい.NET Framework/Silverlight いわゆるTips系やリファレンス系とは異なる書籍で、.NET Frameworkを使ったプログラミングの定石というか王道を語っています。たとえば、Windows Formsではメインスレッドでしかコントロールを操作することができないため、デリゲートを使ってマルチスレッド プログラミングをするとか、FormのLoadイベントは、初期化処理には向かない。なぜなら、何度も呼び出される場合があるからなどです。 この意味で実際に開発して経験したノウハウを形式知化することで、ハマらないアプリケーション開発=高品質な業務アプリを作れるようにすることを目指した書籍です。中でもChapter4「チューニング」は約40ページあり、著者の論理的思考を裏付けるためのノウハウで満載です。チューニングは、先入観よりプロファイリングした結果に基づいてボトルネックに対処すべしというものです。試行錯誤するよりも、プロファイラで事実を把握することが、チューニングの王道であり、早道だということを丁寧に書かれています。  この意味で業務アプリケーションの実装方法を検討される方には、メリットがあるかと思います。もっとも、経験を積まれた方には、周知のことが多すぎるかも知れません。が、この経験した知識を形式知化したところにこそ本書の意義があると言えるでしょう。 PS.かなり前に読み終わったのですが、書評をまとめる時間がとれませんでした。お陰で、もう一度、査読することができました。

2

Rack ベースの Web アプリを IIS で動かしてみました

前回にご紹介した Railsカンファレンスの IronRuby on Railsセッションで、Rails以外のWebフレームワークとしてrackが紹介されていました。rackは、Ruby向けの Webインターフェースを提供するフレームワークで、Ruby on Rails 2.3.x系も内部でrackと統合されています。このrackをIronRubyを使って、IISで動かしてみました。その動かし方を以下に記載します。 1.必要なもの IronRuby 0.5.0 rack 1.0.0 IronRuby.Rack Ruby 1.8系 2.rackのインストール 「igem install rack」コマンドでインストールします。私の場合は、PATHとGEM_PATH環境変数を設定後に実行しました。実行すると以下のようなメッセージが出力されます。C:>igem install rack Successfully installed rack-1.0.0 1 gem installed Installing ri documentation for rack-1.0.0… Installing RDoc documentation for rack-1.0.0… mscorlib:0:in `GetBytes’: 値が有効な範囲にありません。 (System::Text::EncoderFallbackException) from :0:in `write’ from :0:in `puts’ from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/ user_interaction.rb:227:in`alert_error’ from c:/ruby/lib/ruby/site_ruby/1.8/rubygems/ user_interaction.rb:103:in`alert_error’…

0

IronRuby で Ruby on Rails を動かしてみました

昨年のRailsカンファレンスに続いて今年のRailsカンファレンスでは、「IronRuby on Rails」というセッションが行われました。このセッションでは、公開されたIronRuby 0.5.0とRuby on Rails 2.3.2を使って実際にRailsをIronRubyで動かしています。少し(大分かも)前から、IronRubyでRailsを動かすためのドキュメントが公開されています。このカンファレンスで何を紹介したかというサマリーが、Jimmyさんのブログで紹介されています。Railsを動かすドキュメントを使って、実際にRailsを動かしてみましたので、その手順を以下に記載していきます。 1.環境構築 IronRuby 0.5.0 Ruby 1.8系 (私は、OneClick Installer 1.8.6-27を使用しました) IronRuby 0.5.0をダウンロードしてC:\IronRuby-0.5.0フォルダへ展開し、OneClick Installerで使ってC:\RubyへRubyをインストールしました。 2.Rails 2.3.2 の導入 RubyGems のアップデート Ruby on Rails 2.3.2をRubyGemsを使ってインストール#コマンドプロンプトで作業 gem update –system gem install rails –v2.3.2 –include-dependencies  (注)RubyGemsを利用するために、Ruby 1.8系が必要になります。 3.環境変数の設定 PATH環境変数へ IronRubyのBinフォルダへのパスを追加します。 GEM_PATH環境変数へRubyGemsのパスを設定します。SET PATH=%PATH%;C:\IronRuby-0.5.0\bin SET GEM_PATH=C:\ruby\lib\ruby\gems\1.8   4.IronRubyの構成ファイルである「ir.exe.config」のLibralyPathsの値にRuby1.8のライブラリパスを設定します。<set language=”Ruby” value=”..\lib\IronRuby; c:\ruby\lib\ruby\site_ruby\1.8\; c:\ruby\lib\ruby\1.8\” option=”LibraryPaths” /> (注)valueの値は読みやすいように改行していますが、実際に設定する場合は改行を含めないで下さい。またir.exe.configは、IronRuby 0.5.0を展開した中のBinサブフォルダに存在します。 4.SQL…

4