2011-12-31
■2011年お気に入り作品感謝リスト 
例年クリスマスシーズンから年末にかけて書いていた感謝祭的なリストの2011年版です。
- 相対性理論+渋谷慶一郎 - アワーミュージック
- 相対性理論はこれまでほとんど1回聴いてスルーに近い状態だったのですが、これは作風が全然違い、今年一番リピートしていた曲です。病みつきで聞いていました。特別にコメントすることも無いのですが、やくしまるえつこの声がハマる。
- BridJ
- 会社を追い出されて(ry、次の会社(ryに入るまで、暇な時間がたっぷりできたときに、JavaでP/Invokeと同じくらい簡単なものがほしいと思ってJNAのクローンを作っていた時に発見したもので、直ちに自分のハッキング計画を投げ出したくなるくらいよく出来ていてかつ野心的なプロジェクトでした。休職期間が短すぎたこともあってAndroidサポートだけ協力させてもらいましたが、作者のochafik氏がたいへんsupportiveで、ひさしぶりにOSS活動を楽しませてもらいました。
- @ryu_umemoto
- (作品ではありませんが)FM音源使いの - というほど最近は使ってないですが - 僕にとってFM音源の魔術師のような氏はただひたすらスゲー人でした。僕はほとんど成人向けゲームに手を出さなかったので、彼が曲提供されていたゲームも実はほとんど知らず、yu-noとかも見てみたいんですが、PC98版でとなると(音源が目当てなので)、いろいろ難しいようです。僕が訃報を目にした時は札幌に出ていて、途方に暮れて小一時間ばかり呆然と市街をさまよってしまいました。この界隈ではシナリオの人も最近なくなったそうで、知っている人には寂しい話なのだろうと思います。夏の終わり頃は彼の作品を何度も聴いていました。
- 英雄伝説 空の軌跡シリーズ
- 僕の200時間を返せという気持ちでいっぱいです。本当にありがとうございました。冗談はさておき、Falcomのゲームとしては、EDシリーズはどうも苦手で(プレイ時間が冗長すぎる)、今まで1,2,3,4,6しかやったことがなく、First Chapterもぱっとしないという印象だったので、Second Chapterは手を出していなかったのですが、震災の後どうにもやる気が出なかった時についうっかり始めてしまったら…意外にも話が面白い。それにしても長すぎたので、クリアした時3rdは来年にでもやろうと決めたのですが、その2週間後くらいには3rdを始めてしまい…今度は音楽が良く出来てる(話は…)。これは無限ループで再生できなくてどうすると思って、Androidで↑のBridJを使ってtremoloを直接叩いてAndroid SDKのAPIでは出来ないことをやるアプリを書いて、Marketに置いてしまう程度にはハマりました。つい先日も冬休みということで"零"をクリアしたばかりなのですが、また長大な時間を費やしてしまったので、"碧"はもうしばらくやらないつもりです。
- Reactive Extensions
- .NETにもまだ面白いライブラリがあった! 非同期処理がアツイというのはまあ今年?よく言われていましたが、mcsはもうasync/awaitをサポートしちゃったし別に自分は使う立場でしかないからいいかなーと思ってスルーしていたのですが(それ以前に今年はあんまり.NETらしいコードを書いていないか)、RxはEventHandlerやらAsyncCallbackやらを無理なく統一的に操れそうで、興味深いアプローチとして見ています。この辺のブログエントリにあるコードサンプルがRx適用のbefore/afterとしては面白いですね。Rxまわりはneue.ccでいろいろ書かれているので日本語情報が読めるのもイイです(ここで今さら紹介の二番煎じをすることもないでしょう)。そのうちMono for Androidにも適用できるようにしようと思っています。
…まだいくつか今年になって発見できた古い作品もあるのですが、ちまちまとtwitterで書いたりなどしていたので、今年のぶんはこのくらいにしておこうと思います。来年も素晴らしい作品に会えるのを楽しみにしています。
2011-12-20
■CXXIがクロスプラットフォームでC++/C# interopを実現する(予定) 
monoチームからCXXIという新しいコンポーネントが登場しました。これはC++とC#のinteroperabilityを実現するフレームワークだそうです。
》 CXXI: Briding the C++ and C# worlds. http://tirania.org/blog/archive/2011/Dec-19.html
以前からcppinteropという名前で作っていたハカーたちがいて、7月のMonospace conferenceでも発表されていたのですが、それがブラッシュアップされて登場したのがコレです。
》 mono / cxxi https://github.com/mono/cxxi
以下、6割方↑記事の内容を引っ張ってきています。
CXXIの機能・特徴
CXXIが実際にサポートする機能は、ざっと次のようなものだそうです(便宜上C#と.NETはまとめてC#と書きます):
- C++のオブジェクトをC#から操作できる
- C#でC++のオブジェクトを生成できる
- C++クラスのメソッドをC#から呼び出す
- gccに-fkeep-inline-functionsなどを指定すればインラインメソッドも呼び出し可能
- C++クラスをC#で派生できる
- C++のメソッドをC#でオーバーライドできる
- C++のクラスやC++/C#の混合クラスを、ネイティブクラスであるかのようにC#またはC++に公開できる
通常のP/InvokeやMarshalByRefObjectよりは、C++を実用的に使えるものと言えるでしょう。他のC++ interopはどうなっていたんでしょうか?
- Microsoftの.NETの場合は(まあmono on Windowsにもありますが)COM interopがありました。これはC++のクラスをCOM化しないとできません。めんどくさいですね。(そもそもCOMはVBとC++のコード共有のために存在している側面もあるので、RCW/CCWの呼び出し規約が直感的でないのは仕方ないとも言えます。)
- C++の内容を呼び出すCのコードを作成することもできます。(.NETとは無関係に)Cヘッダを公開しているけど中身はC++で書かれているようなライブラリでは、この手法を採用しているものが多いと思います(具体的なコード例が先のリンク先にあります)。これは数が増えるとめんどくさいですし、メソッドをオーバーライドすることもできません(swigもそうですね)。
- Microsoftは、C++/CLIという別のアプローチを採用しました。これはmixed mode assemblyというネイティブとマネージドの混合アセンブリを生成するもので、生成されたコードには可搬性がありません。MicrosoftはWindowsを活かしWindowsと心中する企業なので、それで問題ないのですが、monoにはクロスプラットフォームのやり方が必要ですし相応しいでしょう。
CXXIランタイム
ではCXXIはどのように実装されているのかというと、バイナリレベルでC++のオブジェクトの内容を読み取って、それをもとにC#ベースのクラス構造やメソッド呼び出しを実現します。その具体的な仕組みを知るために、まずC++でコンパイルされたネイティブコードがどのようなバイナリ構造をもっているかを知る必要があるでしょう:
- オブジェクトレイアウト: CXXIではプラットフォーム依存のメモリ上のバイナリ構造をもとに、オブジェクト情報を保持しています。これはコンパイラやプラットフォームによってバラバラなので、それぞれに合わせて動作することになります。
- vtableレイアウト: これはクラス階層構造における仮想メソッドのオーバーライドを実現するために用いられるバイナリ構造です。(一般的に)vtableは関数ポインタを保持していて、メソッドがオーバーライドされたオブジェクトの場合は基底クラスと異なる関数を指し示すことになります。ちなみに非仮想メソッドはvtableには含まれず、Cの関数としてコンパイルされることになります。
- mangled name: C++コンパイラはCコンパイラであり、コンパイルされたオブジェクトコードには、ソースコード上のメソッド名にそれぞれの命名規則を適用して生成された名前をもつ関数が含まれています。この命名規則はコンパイラ依存で、逆に言えばそれに従ってさえいれば、バイナリレベルでのinteroperabilityが実現できるというわけです(名前さえ分かればP/Invokeと同じように名前から関数のアドレスを知ることが出来ます)。
これらがどのようにコード上で展開されるかは上記リンク先に例があります。
CXXIでは、引数やオブジェクト自体のメモリレイアウトを操作するために、プラットフォーム依存のオブジェクトレイアウトを知る必要があり、また非仮想メソッドを呼び出すためにmangled nameを把握しておく必要があります。
以上でも随所で説明しましたが、CXXIは、その仕組み上、プラットフォーム/アーキテクチャとコンパイラに依存します。
CXXIでは、対象ライブラリのC++ヘッダを入力として、CXXIランタイム(Mono.Cxxi.dll)を経由してC++オブジェクトを操作するC#クラスのソースを生成します。

CXXIランタイムの実際の動作は次のような感じになります:
- C#でクラスのインスタンスを生成すると、C++でインスタンスが生成されます。
- 生成されたC#コードのクラスは、C#で派生クラスを定義するのに利用できます。C++の仮想関数は仮想メソッドとなり、オーバーライドすればそれが呼び出せます。
- C++の多重継承に対応しています。具体的には、生成されたC#のコードには、多重継承したクラスに対応する型へのキャスト演算子オーバーロードが追加されるので、それらを利用します。
- オーバーライドされたメソッドでは、baseを呼び出して、C++コード上にある基底クラスの実装を呼び出すことができます。
- 多重継承したクラスにある仮想メソッドをオーバーライドすることができます。
- (自分で生成せずに)既存のC++インスタンスをラップするようなC#のオブジェクト(peer)を生成することもできます。
CXXIジェネレータの仕組み
次はCXXIでC++ヘッダからC#ソースを生成するジェネレータについて。CXXIでは、C++ヘッダからgcc-xml(gcc4の中間コードgimpleのXML表現にコンバートするツール)で生成したXMLを入力として、C#のソースを生成します。生成されるのはソースなので、これに手を加えて最終的なライブラリを生成できます。

ここでポイントとなるのは、生成されたC#コードには、具体的なメモリレイアウトに当てはめられたオブジェクトの情報が含まれているわけではない、つまりまだ環境/アーキテクチャ中立のコードになっている、ということです。具体的なメモリレイアウトの解決は、実行時に行われます。
(ジェネレータではgcc-xmlのみをサポートしていますが、生成されるC#ソースにはgcc依存の部分もMSVC依存の部分も存在せず、またC#ソースの生成に必要なのはヘッダファイルのみなので、gccで解析できるヘッダファイルでさえあれば、困ることは無いはずです。Windowsのヘッダファイルの多くは、cygwinにも含まれるgcc-mingwのw32apiパッケージにも含まれています。)
現状と今後
CXXIは大きな実用の可能性を見せるものですが、未完成の部分もいくつかあります。
- 現在のcxxiは、System.Reflection.Emitを利用してブリッジを動的に生成しています。これで動的にC++コンパイラのABIに合わせて対応できるようになっています。静的コンパイルは出来ていません(iPhoneやPS3環境はまだ)。
- 現在のcxxiはgcc / Itanium ABIにのみ対応しています。MSVC ABI対応のコードは存在しますが、未完成です。(わたしの理解が正しければ、armeabiにも対応していません。)
- 現在のcxxiでは、deleteできるオブジェクトは、C#から生成したオブジェクトのみです。そうでないオブジェクトは、自分でdeleteする必要があります。
--
というわけで、CXXIのざっとした説明でした。わたしの理解では、cxxiが目指しているのはid:atsushieno:20110628:p1 で書いたBridJやJNAeratorのようなツールなんだろうと思っています。Javaの世界では、この種のC++バインディングツールが百花繚乱というか、それぞれ利点と欠点があって、それぞれが短いライフサイクルで生きているなあという印象がありましたが、C#のバインディングツールとして、CXXIもこれまでのツールとは一線を画した存在として、一石を投じることになりそうです。
2011-12-06
■Mono for Android 4.0がリリースされました 
http://android.xamarin.com/Releases/Mono_for_Android_4/Release_4.0.0
いきなり4.0と銘打っていますが、当初Mono for Android 2.0と言われていたやつのマーケティング的な番号の変更にすぎないので、実態はこれまで1.9.xとして出していたものとそれほど変わりません。
…と言いたいところですが、実際には1.9.2から内部的には小さくない変更が加えられています。ここには1.9.0のリリース以来何も書いていなかったので、1.9.1-4.0.0の間に行われた変更について、一度まとめておこうと思います。
Android 4.0 (IceCreamSandwich) support
MfA 1.9.2で、ICSに対応しました。Honeycombの時はタブレットを用意してHoneycombGalleryというサンプルを移植して動作確認できたのですが、ICS端末はまだ手元に来るほど出回っておらず、BeamとかNFCとか(あ、かぶってるか)wifidirectとか、新機能を利用するサンプルの多くがデバイス前提なので、とりあえずAPIバインディングは用意したというレベルです。
ICS対応については、重要な変更があります。それは、Android 4.0で加えられたdalvik VMのJNIのメモリモデルの変更によって、従来のMfAでビルドされたアプリケーションが動作しなくなっている(!)という問題に対応するものです。ICS上で動作するapkをビルドするためには、MfA 4.0で改めてビルドし直す必要があります。
(従来のAndroidのJNIでは、local referenceとglobal referenceを区別できなかったため、MfAに含まれるmonoランタイムのGCでも、これらを区別して扱うことはなかった(できなかった)というわけです。JNIメモリモデルの変更は、Androidで今後Copying GCを導入するにあたって解決する必要があった問題と言えます。)
ちなみに、この変更に関連するものとして、MCW (Managed Callable Wrapper)として作成されていたクラスでは、IntPtrだけを取るコンストラクタを、IntPtrとJniHandleOwnershipという2つの引数を取るコンストラクタに変更する必要がありました。もしユーザーレベルでカスタムバインディングコードを作成していた場合は、同様の変更を加える必要があります。
fast deployment support
Titanium Mobileにはfastdevというアプローチがあり、開発中のアプリケーションのapkを全てまとめてインストールすることなく、アプリケーションのコードを変更して実行できるようにするものです。Androidの特にarmエミュレータは非常に遅く、apkをインストールするだけでも何秒も待たされてイライラすることになります。apkをインストールするということは、アプリケーション全体をインストールするということです。
Android SDK r14以降では、apkの作成時に、更新されていないファイルの再アーカイブをスキップする改善が加えられましたが、apk全体を転送しなければならないことに変わりはなく、依然としてしばらく待たされることに変わりはありません。
Mono for Androidの場合、開発時(デバッグ中)のランタイムは、Market等で配布するためのリリースビルドとは異なり、開発機に別途インストールされた共有ランタイムパッケージを利用しています。デバッグ時にビルドされたアプリケーションのapkに含まれて実際に転送されるのは、アプリケーションのコードのみであり、全体をパッケージして長大な転送処理を行うようなことにはなっていません。
そんなわけで、デバッグのパッケージの転送には、長大な時間がかかっていたわけではないのですが(共有ランタイムが入っていない環境でデバッグを開始した場合は、共有ランタイムをインストールすることになるので、これはもちろん時間がかかりますが初回のみです)、fast deploymentでは、この部分にさらに改良を加えます。fast deploymentモードでは、コードにのみ変更がある場合、apkの再インストールは行われません。更新されたファイルのみが転送され、アプリケーションのフォルダ内で更新されます。
fast deploymentモードは、ストレートに実行する場合よりは複雑な処理を伴う以上、安定性に対する不安が無いとは言えないので、プロジェクト設定でoffにすることもできます。
起動時間の短縮
MfAアプリケーションは、apkの中にmonoランタイムが含まれていて、これをネイティブコードとして実行して初期化し、さらにJavaクラスをJNIでやりとりできるようにmono for androidのランタイムに登録するところから始めなければなりません。これが起動時間が長くなる原因なのですが、今回のバージョンではこの部分に大きな改良が加えられ、起動時間を開発者の実機環境で2.451秒から1.141秒までに短縮することに成功しています。
実際には遅延読み込みに切り替えているので、後で必要になったら読み込み処理が行われることに変わりはないのですが、起動時間の改善は多くの人から要望として上がっていたことでもあり、大きな改善になったと思います。
Google Maps API binding
これはMfA 1.9.2でICSサポートと同時に追加されたAPIで、google APIの対応するライブラリのバインディングということになります。Google Maps APIを使いたい人にとっては普通に便利でしょうし、今後追加される機能を示唆するものでもあります。
アプリケーションサイズの縮小
これはMfA 1.9.1で行われた改良のひとつで、実際にはリリースビルドに含まれるアセンブリを大きく縮小したということになります。
MonoTouchやそれ以前のmonoを知っている人は(わたしもこれまで何度か書いていますが)、cecil linker / tunerというツールが、アプリケーションで使用されていないコードを参照アセンブリから削り落とすことが出来るという話を知っているかもしれませんが、MfA 1.9.1では、(それ以前からlinkerは使用されていましたが)これがより効果的に作用するように、Mono.Android.dllに改良を加えています。リリースノートにも例が載っていますが、4MBだったアプリケーションが3MB以下に収まるようになっています。
おまけ: generic API bindingの拡大
従来のMfAではJava genericsが使用されているクラスのバインディングのサポートは限定的なもので、AdapterView<T>みたいな重要なクラスだけが実は手動で追加されているのですが、今回のリリースで、これまでサポートしていなかったジェネリッククラスやジェネリックメソッドに依存するメンバーを拾えるように改良を加えました。
Javaと.NETの両方のジェネリクスに詳しい人は(なかなかいないと思いますが)、これらが性格を異にし相性が悪いことを知っているかもしれません。erased genericやvarianceの違い、constraintの違いなど、問題がいくつもあります。この辺を改良してAPI coverageを広げたいというのがわたしの希望で、今回ある程度納得の出来る範囲でこれを実現できたことになります。個人的に大きいのはParcelable.Creator<T>を取り込めたことで、出来ることが広がっています。がこの話はまた今度。
というわけで
今回のMono for Androidのリリースが、今年最後のものになると思いますが、これまでにない数多くの改善が加えられた the latest and greatest releaseになっていると思います。Mono for Android 1.2の頃と比べて、だいぶ変わってきたと思います。
ちなみに先月はXamarin本社でミーティングがあって、チームメンバーが開発しているものを見せてもらったりしてきたのですが、今後のMfAにも割とビックリするような新機能が追加されそうで、既に公開される日が待ち遠しいところです。
2011-12-03
■12/10 MfA GC at マーク&スイープ勉強会 
来週は id:n7shi:20111113:1321190227 におじゃましてMono for AndroidのGCの話をちょろっとだけしてきます。
…のつもりだったのですが、20分くらいあるようなので、mono本体のGCまわりの話からいろいろしようかと思います(本当はMfAのGCまわりでどんな作業が行われていた(いる)か、Android 4.0でどんなことが起こるか、だけでお茶を濁すつもりだったのですが)。今までも各所でちょろっとだけお話ししてきたことですが、わりと大変なんです。
ちなみに僕はGCまわりはど素人に近いし開発にも全くタッチしていないので、実装のディープな話が出来る予定はほとんどありません。昨日ちょろちょろとスライドを作っていたんですが、「さわり」だけになると思います。20分に収まるかどうか微妙な長さの「さわり」ですが…。Ice Cream Sandwichで変わった部分の話なども含める予定です。
というわけで、もし興味を持たれた方がいらっしゃったら是非おいでくださいませ。
2011-10-25
■Instrumentationからアプリケーションにフックを仕掛ける 
もう2週間以上前に書いて新バージョンのリリースまで待っていたんだけど、いつまでたっても自分の対応コードがまともに取り込まれない事態に業を煮やしたので、先に文章を上げてしまおうと思う。書いたのが古いので多少時間がおかしいのは目をつぶってやって下さいまし。
--
Mono for Android(以下MfA)はクローズドソースなので、中がどうなっているのかサッパリ分からないかもしれないが、実は表からでも分かることが少々ある。今日はそのひとつの例として、mono for Androidにおけるmonoランタイムのbootstrapについて、Androidアプリケーションの仕組みに言及しつつ触れてみたい。
MfAのアプリケーションは、debugビルドとreleaseビルドで構成が大きく変わるものの、基本的な構成としては、どちらも通常のAndroidアプリケーションだ。通常のアプリケーションというのは、AndroidManifest.xmlやclasses.dexを含むapkのzipアーカイブになっているということだ。Monoランタイムも、通常のAndroidアプリケーションにおけるネイティブライブラリとしてビルドされて含まれている。
MfAのランタイムは、ContentProviderのひとつとして、ビルドされたアプリケーション上に登録されている。このことはMfAアプリケーションに含まれるAndroidManifest.xmlを覗いてみると分かる。MfAはprovider要素として登録されているのだ。ContentProviderは、attachInfo()の呼び出しによって、アプリケーションのContextやProviderInfoと関連付けられる。ここでアプリケーションの情報をもとにmonoランタイムが初期化されていると想像することは、難しくないだろう(アプリケーションの情報が全く無いと、そのapkにどのライブラリが含まれているかも分からなかったりして、いろいろ不自由がある)。monoランタイムの初期化以前はmonoの機能は何も使えないので、ここでmonoをbootstrapするContentProviderはJavaで書かれている。その実装はJNIを経由したCのコードだ。
いったんmonoランタイムがセットアップされると、そこでJNIのRegisterNatives()を呼び出してJavaクラスを登録すこともできるし、必要に応じてJavaのコードからJNI経由でmonoの組み込みAPIを呼び出すこともできるようになる。MfAは、Android Callable Wrapper (ACW)という名前で、Monoランタイム上のオブジェクト(つまりC#/.NETのコード)からDalvik上のJavaオブジェクトを呼び出すことができる機能を呼んでいるのだけど、このACWを実現するために、C#/.NETのクラスから自動生成されたJavaクラスをRegisterNativesで登録している。
このContent ProviderとしてMfAのような外部ランタイムを登録するアプローチは、ほとんどの場合には適用できるが、実はこれが上手く行かないケースがある。それがInstrumentationだ。
Instrumentationが何をするものか、どう使われるのか、については、Android SDKのリファレンスを参照してもらいたい。Instrumentationについては、前回Native Driverについて書いた時も言及している。
http://www.techdoctranslator.com/android/guide/manifest/instrumentation-element
このInstrumentationは、Applicationよりも前にインスタンスが生成されることになる。もちろんAndroidManifest.xmlに記述されているContentProviderのインスタンスよりも前だ。これはandroid.app.ActivityThreadの中身を読めるようになると分かる。
Androidのアプリケーションの動作の仕組みまで詳しい人はなかなかいないと思うけど、基本的にはWindows APIのメッセージループ(WndProcとか)、CoreFoundation/Cocoaのイベントループ、X11のXEventのループ、GLibのメインループと似たようなイベントループが存在している。
http://en.wikipedia.org/wiki/Event_loop
ActivityThreadは、アプリケーションのメインスレッドと理解できる。アプリケーションの起動については、ちょうど最近じつに詳細なまとめが公開されたので、参考にすると良いと思う。
http://dsas.blog.klab.org/archives/52003951.html
先のandroid.app.ActivityThreadのソースのリンクは、handleBindApplication()というメソッドを示していて、これは中でApplicationインスタンスの生成を行っている。
このメソッドの中で、ContentProviderの生成とattachInfo()の呼び出しも行われているのだが、それ以前にInstrumentationの有無で処理が分岐していることに気づくだろうか。もしアプリケーションがInstrumentation経由で作成される場合は、そのInstrumentationのインスタンスがまず生成され、次にApplicationインスタンスが生成される、という流れになっている。
さて、Instrumentationを使用する場合は、通常は派生クラスを定義することで実現するのだけど、MfAでAndroid.App.Instrumentationの派生クラスを定義した場合はどうなるだろうか。Instrumentation(の派生クラス)の派生クラスのインスタンスは、Applicationの生成とContentProviderの生成より前に行われる。しかしContentProviderの初期化フェーズでMfAランタイムが初期化されないと、MfAを利用して定義したクラスに相当するJavaクラスはまだRegisterNatives()で登録できない。
そんなわけで、Instrumentationを利用する場合は、静的にclasses.dexのみでJavaクラスが解決できていないといけない。MfAみたいに独自のライブラリを使ってJNIのRegisterNatives()を使ってクラスを登録しなければならない場合は、Instrumentationにも気をつけたほうが良い。
いったんInstrumentationのクラスを作成したら、あとはそのonCreate()をオーバーライドして、そこに初期化コード(MfAならmonoランタイム初期化コードとか)を追加すると良い。
--
というわけで、これを調べてから、Instrumentationをちゃんと動かせるようなコードを書いてうちのチームに投げたのだけど、ニーズがまだ大きくないため*1他の優先タスクの中に埋もれたままもうひと月ちかく経とうとしていて、次のリリースにも含まれそうにない。とはいえ、そのうち含まれることにはなると思う。
*1:そんなことは無くて作れるものが増えるのだけど、対応しないとコードが書けないというchicken and egg問題
2011-10-16
■slides for スマートフォン勉強会@関東 
昨日のすまべんに参加して話を聞いて下さったみなさまありがとうございました。それなりにいろんな方面のモバイル開発者の方がいらっしゃっていたみたいで*1、予想していたより全然キモくない普通じゃーんと思っていたのですが、後半そして懇親会に流れるに連れて以下自粛
昨日のスライドはこちらに置いておきます。今回は読んでもあまり内容が伝わらないかもしれませんが…
https://docs.google.com/present/view?id=dfbvrv4g_44pxz5vhcc
30分で話せる範囲に絞り込んだはずなのですが、後半話すにつれて、もちっと細かく話さないと伝わらないなあと思うようになって、だいぶん申し訳ない気持ちになったのですが、その辺はおいおいフォローアップしていければと思います。
あと最後に話した件ですが、store... に付けてください。現場にいなかった人でも大丈夫です。
*1:ちなみに本来は開発者対象の集まりですらないらしい、というのは昨日初めて知りました
2011-10-13
■Mono for Android from Xamarin, at スマートフォン勉強会@関東 
事前にお知らせするのを忘れてましたが…表題のイベントでMono for Androidのお話をさせていただくことになりました。
http://sumaben.jp/?SPWorkshopKanto15
実のところ一度も「すまべん」には参加したことが無いので参加される皆さんがどういうキモヲタ層の方々なのか存じあげないのですが、30分なので手短にお話しすることになると思います。C#で書くとこんなに楽チン!みたいな話は、まあしてもいいというかMfAのウリではあるはずですが、今更感があるので、そういうのは少なめにして、なるべく仕組みなど応用のきく話をしようかなと思います。「使い方」を勉強したい人の集まり、ってわけでもないよね…? (そんなに*MfAの*ユーザーの人が集まれるほどいたら喜んで勉強会開きますw)