2009/10/12

BinaryFormatterにアセンブリバージョンを無視させる

シリアル化、逆シリアル化に使われる
BinaryFormatterクラスについて。

どうやら、
逆シリアル化するときに
BinaryFormatter.AssemblyFormatプロパティに
FormatterAssemblyStyle.Simpleを設定しても、
ちゃんと機能してくれない(アセンブリバージョンの違いなどを無視してくれない)
といバグがあるらしい。
特に、ジェネリックなクラスを逆シリアル化する場合に
この現象が起こるっぽい。

回避策としては、
BinnaryFormatter.Binderプロパティに、
SerializationBinder抽象クラスを実装した自作のクラスのインスタンスを設定する
というのが有効のようだ。

で、
SerializationBinderクラスの実装方法。

実装すべきは
Type BindToType( string assemblyName, string typeName )
というメソッドひとつのみ。
名前通りアセンブリ名と型名が引数として渡されるので、
アセンブリバージョンを無視したいなら
return Type.GetType( typeName );
とすればいいんじゃない?
と、思うところだが、そうはいかない場合がある。

ジェネリッククラス(または構造体)の場合、
typeNameには、例えば
List<BinaryFormatterTest.Hoge>
を逆シリアル化するときには、こんな感じの文字列がはいってくる。

System.Collections.Generic.List`1[[BinaryFormatterTest.Hoge, BinaryFormatterTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ef4f1793c250e8fa]]


つまり、型パラメータにアセンブリの厳密名が入ってしまっている。
これを
Type.GetType( typeName );
とすると、
VersionやCulture、PublicKeyTokenがすべて一致するアセンブリが
見つからない場合、例外がスローされる。
なので、アセンブリバージョンとかを無視させたいなら、
Type.GetType()にtypeNameを渡す前に
どうにかしてtypeNameの文字列中から型パラメータの
Versionやらなんやらの文字列を強引に削除しないといけない。

で、以下、そのサンプルコード。
結構、強引にやってますが、なんとかうまくいくみたい。
バグがあったらごめんなさい。



public class IgnoreVersionBinder
: SerializationBinder
{
public override Type BindToType
( string assemblyName, string typeName )
{
int i = typeName.IndexOf( '[' );
while( i >= 0 )
{
i = typeName.IndexOf( ',', i );
int end = typeName.IndexOf( ']', i );
typeName = typeName.Remove( i, end - i );

i = typeName.IndexOf( '[', i );
}

Type t = Type.GetType( typeName, false );
return t;
}
}



2009/08/13

OpenTKが更新中

最近OpenTKの活動が活発になっているようだ。
まだ詳細はみていないが、
現在、正式にリリースされているのはver.0.9.8-2。
でもって、ver.1.0リリースに向けてver.0.9.9も公開が始まっている様子。
なにやらOpenCVなるもののラッパーも追加されたとか。
ver.0.9.9からwindowsでのFSAAをサポートするようになったっぽいが、
まだ試してないのでよくわからん。

2009/05/28

TeX : 索引ページのヘッダ・フッタ

なんか唐突だが、
TeXの小ネタ。

ヘッダやフッタをいろいろいじった文書を
fancyhdr パッケージを使って作ってた。
で、それにはmakeidx パッケージと mendex を使って索引もつけてたのだが、
どういうわけか、\printindex コマンドで出力した索引ページだけは
ヘッダ・フッタが強制的に(デフォルトの設定に)変更される。
fancyhdr を使わずにヘッダ・フッタを設定しても同じようなことが起こる。

まぁ、索引ページにあれこれヘッダ・フッタをつけるな、
と、いうことなのかもしれないが、
状況によっては
ページ番号の位置が索引ページだけ違うところにある、
なんてことにもなるわけで。

いろいろ原因を探ってみたところ、
結局、クラスファイル jsarticle.cls の
theindex 環境の定義に原因があった。
(この theindex 環境は、\printindex コマンドで取り込まれる
*.ind ファイルに書かれているので、直接使用することはない。と思う。)

jsarticle.cls ファイル中の theindex 環境の定義(1400行ちょっとあたり)
\newenvironment{theindex}{%
...

に続く、
\plainifnotempty
というコマンドをコメントアウトすると
(このコマンドがヘッダ・フッタをデフォルトに設定するらしい)
ヘッダ・フッタが索引ページで強制的に変更されることはなくなる。

2009/05/04

誰かが、既にあなたの問題を解決してしまっています。

デザインパターンの本で
なかなか、いや、かなりおもしろいものを見つけた。



「誰かが、既にあなたの問題を解決してしまっています。」は、
本書の冒頭から。

なんというか、とってもユニークな内容の一冊。
もし本屋で見かけたら、是非ちょっと手にとって眺めていただきたい。
ぱらぱらとページをめくってみればわかるが、
全体を通して、一般的な技術書とは雰囲気がまるで違う。
アヒルシミュレータとか、ピザ屋とか、パターンの師匠と弟子とか・・・。
とても理解しやすいし、読みやすいし、飽きない。
デザインパターンなんてややこしそうだし、いいや・・・
なんて思っている人には非常におすすめです。

2009/02/25

C#でジョイスティックをいじってみた

タイトルの通り、
ジョイスティック(=ゲームパッド)をいじってみた。

ジョイスティックを使う手段としての選択肢は
・DirectInput
・SDL
・Win32 API (winmm.dll)
あたりだろうか。

OpenGLを使ってるので、
それと一緒にDrectXを使うってのも変なので
DirectInputは、無しで。

SDLとwinmm.dllは、
どっちもTaoを使えばC#から簡単に使える。

Win32 API を使うと、
ジョイスティックの入力イベントのメッセージが
ウィンドウに飛んでくるようにできるらしいので、
そのメッセージを処理すれば
マウスイベントとかと同様に
ジョイスティックイベントをFormに実装できるかなー、
と目論んで、
winmm.dllからジョイスティック関連の関数を呼び出して
いじってみることにした。

という事で、
まずはwinmm.dllからの関数のインポート。
こういう時に便利なのがここ(Pinvoke.net)なんだけど、
どういうわけか、ジョイスティック関連のAPIが見あたらない。
ってことで、やっぱりTao.Platform.Windows.dllを使うのが一番手っ取り早いかも。

Tao.Platform.Windows.dll の中に、
そのまんま "Winmm" という名前のラッパークラスがあり、
ここにジョイスティック関連のAPIがインポートされてる。
っていうか、このクラスにはほとんどそれぐらいしか無いっぽい。

ジョイスティック関連のAPIの使い方は、
ここがわかりやすいかも。
http://fyhpld.hp.infoseek.co.jp/develop.htm

ジョイスティックをキャプチャすると
ウィンドウにジョイスティックのイベントメッセージが飛んでくるようになるので、
あとは、そのメッセージの処理ルーチンを自前で
ウインドウプロシージャに加えてやればよい。
.NETのコントロールとかフォームだと、
ウインドウプロシージャに相当する
void WndProc( ref Message m )
というメソッドがあるので、
これをオーバーライドしてやればOK。

・・・なんだけど、
TaoのWinmmクラスに定義されてる
ジョイスティック関連のメッセージ(MM_JOY1MOVEとか)、
なんか、ボタンイベントのメッセージ(MM_JOY1BUTTONDOWNとか)が
ぬけてるっぽいな・・・。

あとは、
たとえば、"JoysticMove" みたいな名前でイベントを用意して、
オーバーライドしたWndProcメソッドから
メッセージに応じてイベントを呼び出すようにしてやれば、
マウスイベントと同様に、ジョイスティックイベントが実装できるはず。

2009/01/29

しかし、まぁ、

このブログも、ちと、放置しすぎだな・・・。
ま、どうせこんなのをまともに読んでいる人も
いないだろうけど。

ってなことも、
前にも何度も書いた気がするが・・・。
ま、いいか。

GLSharpは、
バッファオブジェクトのクラスがだいたいできあがって、
それをうまいことMeshModeクラスで使えるように試作中。
あと、MQOローダーをミラーや回転体に対応するように改良中。
いつもどおり、
気が向いたときにちまちまと書いてるだけなので、
ちまちまとしか進んでません。

しかし、
これから
修論とか卒業とか引っ越しとか、いろいろあるから
もっと停滞するんだろうなぁ・・・。
まぁ、修論はほとんどできあがってるけど。 

なんか、ふくらんでる・・・

ずいぶん長いこと使わずに放置していたデジカメ、
ちょっと用があって使おうと思ったのだが、
なぜか電源が入らない・・・。
機種は Panasonic FZ-1。
バッテリーが空になってるのだろうと思って
充電したが、動かない。
ACアダプタで電源供給したら動いたので、
バッテリーがダメになった様子。

・・・なんて、いじっていたら、
ふと気がついた。

なんか、バッテリー、
微妙にふくらんでね?

ぅわ、破裂したりしないよな・・・。


さて、
バッテリーだけ買い換えるか、
いや、まぁ、だいぶ古くなってきたし、
いまどき200万画素では物足りないだろうし、
新しいのを買うかな・・・。