ものがたり(旧)

atsushieno.hatenablog.com に続く

PS Suite SDK public betaでC# 4.0 dynamicを使う

昨日ついにPlayStation Suite (PSS) SDKが公開ベータになりましたね。
http://www.playstation.com/pss/developer/index_j.html

昨日はそのタイミングで行われたSCEAndroidの会のイベントでの話を聞きに行っていました。
http://atnd.org/events/27043?updated_at=1332783364

その内容は id:nakamura001:20120419:1334857193 が詳しいのでそこを見てくださいということにして。

わたしの理解している範囲では、PSSで動いているのは、MonoTouchやMono for Androidと同等の.NET 2.1もどきのランタイムということになります。ランタイムは「もどき」ってほどでもないかな。クラスライブラリは、たとえばXPathNavigatorやXmlSerializerが使える程度には.NET 2.1「ではない」です。これはMTやMfAと同じ匂いがあります。

さて、Mono for Android 4.1にDLRサポートを追加したのはわたしなので、同じ事をPSSでもやってみました。PSSがサポートしているのはC# 4.0相当のコンパイラとそれに対応するCoreCLR相当のクラスライブラリということになり、昨日のイベントでもSCEの方が質問にそう答えていましたが、実はコンパイラの実装であるmcsがC# 4.0をサポートしているだけではdynamic型は使えません。なぜかというと…

  • mcsは、dynamicを使ったコードをコンパイルする際には、Microsoft.CSharp.dllの参照があることを要求します(System.Core.dllを参照に追加してSystem.Linqをusing文でインポートしないとLINQ構文が使えないことと似たような構図です)。
  • そして、monoのMicrosoft.CSharp.dllは、内部的にはMono.CSharp.dllというC#コンパイラの実体を要求します。
  • さらに、System.Core.dllに含まれるExpression TreeのAPIに、DLRをサポートするためのコードが含まれていなければなりません。

これらはどれも現在のPSSには含まれていません。つまり、現在のPSSではC# 4.0相当のコンパイラがあっても、C# 4.0のdynamicは使えないんですね。

今回はこれを無理やり使えるようにします。やることは簡単です。

  • mono本体(git master or mono-2-10)をmonodroidのライブラリビルドのオプション --with-monodroid=yes でビルドする。--with-moonlightや--with-monotouchはダメ(これらはdynamicをサポートしません)。
  • 出来上がったmcs/class/lib/monodroid に含まれるSystem.Core.dll, Microsoft.CSharp.dll, Mono.CSharp.dll を、PSS Studioのアプリケーション プロジェクトで参照に追加する。PSS SDKに含まれるSystem.Core.dllは参照しない(!)

これだけで、PSSアプリケーション プロジェクトでもdynamicが使えるようになります。仕組みとしては、(確認はしていませんが)mcsは、Microsoft.CSharp.dllの参照の有無を見て、dynamicサポートの状態を切り替えるので、これだけでdynamicが有効になる、というわけです。

id:atsushieno:20120406:p1 でも書きましたが、MfA 4.1のサンプルにはdynamicコードの例として、Microsoftが最近公開したaspnetwebstackから引っ張ってきたSystem.Json.dllに含まれるJsonValue.AsDynamic()を使ったものが含まれています。このソースをPSSライブラリプロジェクトに取り込んで、コンパイルオプションにMONODROIDを設定すれば、PSSでもビルドできて、dynamicなJSONが使えるようになります。

ただ、上記エントリでも言及しましたが、dynamicコードはコストを伴うものだということは理解しておいてください。これを実際にやって動かしてみると、デフォルトの空っぽに近い状態では軽快に動作しているように見えるPSSでも、決して軽くはありません。

ちなみに、mono-reactiveに含まれる System.Reactive.Android.csproj と同じ構成で、PSS向けにSystem.Reactive.dllをビルドして使うこともできます。PSSクロスプラットフォーム性を実感してくださいw