WWWWARD跡地 > .NET Claimwork 3.0

概要: WWWWARDは移転を完了しました。

WWWWARDは、移転を完了しました。今後はhttp://w4ard.eplusx.net/でアクセスして下さるようお願いします。

......って一行書く為に何ヶ月かかってんだろこれ。まあ去年の十二月くらいからはしょうがないとして。それはともかく、移すべきものもすべて移したし、リダイレクトも設定したし、これでほとんど問題無いはずです。長かった。

WWWWARDのほとんどのコンテンツは、移転先に向けてpermanentなリダイレクト(301)をさせていますが、このウェブログと更新履歴とトップページだけはそのままにしてあります。更新履歴は(自分を含めて)混乱を避ける為、.NET Claimwork 3.0は移すのが面倒だった為、トップページはそれらの目次用に。

ちなみに、移転先のサーバは自前で、WWWWARD以外にも幾つかバーチャルホストがあります。SounDecoder関係はSounDecodeRepositoryに移しました。前々から言っていた水面下プロジェクトは、CardWirthPhoenixでとりあえずプレースホルダを公開。また、これらのサイトのポータルであるeplusx.netも用意しました。その内他にも増えるかも知れません。

それでは、移転後もWWWWARD及びeplusx.netをよろしくお願いします。

※以後、このウェブログを更新する予定はありません。移転先のウェブログでごにょごにょやってまいります。

概要: むずかしいです。でもうつくしいです。

OpenCVでカメラからのキャプチャを行うような事をC++/CLIでやろうとしています。で、まあリソース管理の為のコードを書くのは避けて通れない訳で、Disposeパターンに従って作ろうとしたら、public: virtual void Dispose(bool);が通らない......予約されていると? と思って見てみたら、こんなページがMSDN Libraryにありました。

URIが日本語用(ja-jp)なのに翻訳されていないというのはとりあえず置いておいて、C#に慣れた頭で読んでみると驚きの連続でした。ついでに眠いせいか難しい。一通り読んだだけでは収拾がつかないので、デストラクタ(Wikipedia)なども見つつ重要そうな所を僕なりにちょっとまとめてみます。

C++/CLIにおけるデストラクタとファイナライザ

デストラクタ

リソース(特にアンマネージドリソース)を積極的に解放する為にあるメソッド。リソースが要らなくなったらすぐ呼ばれるべきもので、スコープを抜ける時に自動的に呼ばれたり、プログラマが明示的に呼んだりする。

C++/CLIではデストラクタ構文(~classname())で表される。.NET FrameworkではIDisposable.Dispose()に相当する。C#はこいつを実装する事でデストラクタの機能を提供する。

ファイナライザ

リソースの解放し忘れによる被害を最小限に抑える為にあるメソッド。ガベージコレクタが使う最後の砦。インスタンスが占有する領域を解放したくなった時、リークが無いかどうか調べて、もしあれば解放する(デストラクトする)為のもの。ガベージコレクタが解放したくならなければ(=メモリがいっぱいあれば)呼ばれない事もあり得る。

C++/CLIではファイナライザ構文(!classname())で表される。.NET FrameworkではObject.Finalize()に相当する。C#におけるファイナライザは、C#ではデストラクタと呼ばれているらしく(初めて知った気がするが気のせいか)、デストラクタ構文(~classname())で表される。

C#のファイナライザがデストラクタと呼ばれているのが混乱を招きそうですが、まあC#の~classname() <=> Finalize()と最初から覚えてしまえば良さそう。

マネージドリソースとアンマネージドリソース

色んな所で出てきますが、おさらい。

マネージドリソース
ガベージコレクタによって管理されるリソース。ガベージコレクタの管轄であるマネージドヒープに作られたオブジェクトの事。C++/CLIのref classオブジェクトとかC#のclassオブジェクトなんかもこれ。幸運にもガベージコレクタが管理できるという色が強い、と思う。
アンマネージドリソース
ガベージコレクタの管轄外にあるリソース。例えばCのmallocや標準C++のnewなどによって、ガベージコレクタが監視できないヒープに確保されたオブジェクトなどが含まれる。ファイルハンドルも代表例の一つ。ガベージコレクタは残念ながらこいつらを自動的に解放する事はできない。

ガベージコレクションにおけるファイナライゼーションの順番

これは、保証されません。マネージドリソースAが別のマネージドリソースBへの参照を持っていた場合などはAからファイナライズすればいいように思えますが、更にBがAへの参照を持つ事もあり得るので、そうなるとどちらからやればいいかは自明ではありません。勿論規則を明確にすればどのような場合でも一意に決められるでしょうが、想像してみると判るように、それを実現する為のコストは割と高い(外部環境の影響を受けないように追加情報(例えばインスタンス化時刻とか)を載せなければならない)ですし、第一人間がそんなもの把握しきれません。

となると、です。オブジェクトAのファイナライザが呼ばれた時には、オブジェクトBのファイナライザは既に呼ばれているかも知れません。ファイナライゼーションが済んでしまえばガベージコレクタはそのオブジェクトが占有していたメモリ領域を解放しますから、今までBへの正しい参照だったものは危険な(使ってはいけない)参照になります。そしてBのファイナライゼーションが既に行われたかどうかを知る術はAにはありません。ファイナライザでは、マネージドリソースへの参照を使ってはいけないのです。

もしBがアンマネージドリソースだった場合は逆で、むしろ責任を持って解放してやる必要があります。ガベージコレクタがアンマネージドリソースをファイナライズする事はありませんし、BがAによってのみ所有されていれば、AはBのファイナライゼーションが済んだかどうかは正確に把握できるはずです。

Disposeパターン

こうなってくると、デストラクタでは場合分けが必要になる事が判ります。明示的に(ファイナライゼーションよりも早い段階で)デストラクトされる場合と、ファイナライゼーションによってデストラクトされる場合です。この為に、C#などではboolをパラメータとするDisposeメソッドを用意する事が推奨されています。Disposeパターンと呼ばれるようです?

public class MyClass {
  // disposingがtrueであればマネージドリソースのデストラクトも行う
  // アンマネージドリソースのデストラクトはdisposingの値に依らず行う
  // 派生クラスでやる内容変わるだろうからvirtualに
  protected virtual void Dispose( bool disposing ) {
    try {
      if ( disposing ) {
        // (マネージドリソースのデストラクト)
      }
      // (アンマネージドリソースのデストラクト)
    }
    finally {
      // もし親がいれば
      //base.Dispose( disposing );
    }
  }
  // デストラクタ
  // マネージド、アンマネージド両方とも解放
  public void Dispose() {
    // 明示的なデストラクション
    this.Dispose( true );
    System.GC.SuppressFinalize( this );
  }
  // ファイナライザ(デストラクタ構文)
  // アンマネージドリソースのみ解放
  ~MyClass() {
    // ガベージコレクタによるデストラクション
    this.Dispose( false );
  }
}

C++/CLIにおけるDisposeパターン等価コード

先程のコードを、C++/CLIで書くと次のようになります。

public ref class MyClass {
  // デストラクタ
  // マネージド、アンマネージド両方とも解放
  ~MyClass() {
    // (マネージドリソースのデストラクト)
    this->!MyClass();
  }
  // ファイナライザ
  // アンマネージドリソースのみ解放
  !MyClass() {
    // (アンマネージドリソースのデストラクト)
  }
};

美しい。これで等価だそうです。SuppressFinalize(Object)の所まで含めて。

このように書くと、デストラクタ構文の方は強いデストラクションをやっていて、ファイナライザ構文の方は弱いデストラクションをやっているようにも見えてきます。

まとめ

ま、上に書いた事がすべてではありますが、一応。

  • C++/CLIでは、DisposeやFinalizeなどのメソッドは文字通り書く事は無い。デストラクタ構文、ファイナライザ構文を使う。
  • ファイナライザでは他のマネージドリソースをデストラクトするべきではない
  • 明示的にデストラクタが呼ばれればマネージドリソースも含めてデストラクトするべきで(強いデストラクション)、
  • ガベージコレクタのファイナライゼーションで初めてデストラクタが呼ばれるようなら、マネージドリソースはデストラクトすべきではない(弱いデストラクション)。
  • C++/CLIでは、強いデストラクションをデストラクタ構文で、弱いデストラクションをファイナライザ構文で書く
  • つまり、デストラクタではマネージドリソースを解放した上でファイナライザを呼び出し
  • ファイナライザでアンマネージドリソースを解放する

うん。読みながら理解しようとしていた時には混乱しかけていたけれど、まとめてみれば何て事無い、とても素直で綺麗な設計だと思います。さすがはリソース管理にうるさい(?)C++が前身の言語と言うべき? 気をつける事と言えば、C#ではファイナライザ(デストラクタ構文)がDispose(bool)を呼び出すのが普通なので、一見逆の事をやっているように見える事ですね。実際やっている事は同じだと。ふむ。

概要: OpenMPを利用すると、さほど労力をかけずプログラムを並列化できるようです。自分ではまだ試していませんがかなり面白そう。

自分で頑張ってスレッド作って、複数スレッド間で頑張って同期したりしなくても、コード中にヒントを書いておけば勝手に並列化してくれる(と思う)OpenMPなんてのがあるそうです。概要掴むにはWikipediaにあるOpenMPの記事が役に立ちます。

当然ながらアプリケーションの複数スレッド間で資源が競合しないようにする為には元のソースコードに対する深い知識が必要ですが、OpenMPはコンパイラが使うミドルウェアといった感じのようです。コンパイラによるサポートが必要ですが、gccのC++コンパイラやVisual C++のclといった(独断と偏見によれば)メジャーなコンパイラではサポートされているようです。コンパイラは当然元のソースコードをよく知っていますから、うまく動くって訳ですね。ちなみにVisual C++の場合はVisual C++ の OpenMPを読むと良さそう。

こいつを知ったのは、最近OpenCVを入れたのですが、そこでOpenMPが使われていたからです。なるほど画像処理でも局所性が高いものが多いでしょう。スレッドを分ける要請は無いものの、CPU余ってるなら使いたいと。で、OpenMPという訳か。

ミドルウェアで思い出しましたが、Globusってのもあったなあ。こちらは複数台のコンピュータを使って一つのタスクをする(つまり、グリッドコンピューティングをする)為のミドルウェアだそうですが、前から入れよう入れよう思っているものの全然調べてない......。まあうちのとこのサーバ群も遊んでるマシンは少なくなってきてはいますが。

概要: Movable Type 5の出荷日が11月26日に決まったそうです。同時期に移転したい所です。

おお、ようやく!

案の定下旬(11月26日)ですが、まあ11月中には違いない。

さあ、こっちの方も暇を見つけて頑張らなきゃなあ。本業(?)の方と並行して、相補的に進めばいいんですけど。

概要: Movable Type 5の出荷が11月後半に延期になったそうです。

だそうです。ちょっと残念。まあそれまでの間にちょっと雰囲気変えてみたりSounDecoderのドキュメント整備してみたりしていますか。

概要: 近々、このサイト(WWWWARD)を移転する予定です。それでも、今あるコンテンツについてはできる限りリンク切れが起こらないようにする......つもり。

今、このサイトはXREAの無料ウェブホスティングサービス(?)を利用しています。無料という事で当然広告は出さなければいけないのですが、とても住み心地が良い所で、もうかれこれ3年以上利用させて頂いています。しかし、このサイトのディスク占有量が無料サービスの上限である50MBに迫ってきている(ほとんどMovable Typeのせいなのですが)事と、最近一台お下がりをもらって自宅にサーバ専用機を作ったので、近々そちらに移転する予定です。

DNS登録は、最初はDynDNS.comでやろうかと思ったのですが、どうもDynDNS.comでは無料でバーチャルサーバの為の設定を行う事ができなくなったらしい(Wildcard StatusがDisabledになっていて、Want wildcard support?というリンクを辿るとDynamic DNS Proという$15/yearの有料サービスを案内される)事と、どうせなら.netとか.infoなどのドメインがいいなあと思い、VALUE DOMAINで何かしら取るつもりです。

これによって勿論URIは変わりますが、今までのhttp://w4ard.s26.xrea.com/以下へのアクセスは、新しいURIにリダイレクトする事で、できる限りリンク切れは避けようと思います。但し、このウェブログ(.NET Claimwork 3.0)は当初予定していたよりも大分内容がまぜこぜになってしまったので、新サイトでは新しくウェブログをジャンルごとに幾つかに分けて作成し、このウェブログの内容は引き継がずにこのウェブログ自体をそのまま残そうと思っています。気が向いたら移行するかも知れませんが、多分そうはならないでしょう。

Movable Type 5の個人ライセンス提供開始に合わせて最終調整、移転をしようかと思っているのですが、通常ライセンスと同時に出るのでしょうか、Movable Type 5の正式出荷は10月何日なのでしょうか。そもそも何でまたこんな時間まで起きているのでしょうか......。

概要: とりあえず、SounDecoder Soundsのプログラムコード例を、簡単なものですが書きました。

先月の中旬まではまあいいとして、その後完全にほったらかしにしていたSounDecoder Soundsのプログラム例。まあ忙しかったというのはありますが、それにしてもこれ以上ほったらかすとまた以前と同じなので(もう同じかも知れませんが)、とりあえず基本的な所だけ、えいやと書いてみました。こんなの言われなくても判るレベルとか、SounDecoder Playerの方がまだ参考になりそうとか、思う所は多々あるにせよ、今後充実させていく為の前置きとして。

それにしても、以前些細な事でもこまめに書こうとか思ったはずなのに、相変わらずひどい放置ぶり。一回当たりのワークロードを軽くするように、ほんと心掛けねば......。

概要: SounDecoderとSounDecoder Sounds MDXの最新版を公開しました。これで.NET環境から簡単にサウンドの再生ができるライブラリは一通り揃いましたが、まだプログラム例はできていません。

何とかかんとか、公開にこぎ着けました......。最終版をビルドしようとしたら直前になってバグが出てくるわ(結局DirectSoundのバグだったみたいで(違うかも知れませんが)、今は直してあります)、周辺の文書整備してたら予想外に時間を食うわで結局一日中はおろか八月中に出すのも無理でしたが......(最初はこれ今年の春休み中に完成させようと思っていたのは内緒だ)。

SounDecoderは、コアモジュールだけ0.2.0.0にバージョンアップです。バージョン番号が1上がってるのは一般にはマイナーバージョンの桁ですが、割と重要なアップデートです。というか、SounDecoder 0.2.0.0じゃないとSounDecoder Sounds MDXが使えません。あ、そう言えば依存バージョン書くの忘れた......。

SounDecoder SoundsはSounDecoderを使って手軽にサウンドを再生する為のもので、今回公開したのはManaged DirectXのDirectSoundをラップするMDX 0.1.0.0です。SounDecoder 0.2.0.0以降と一緒に使います。

リファレンスは一応doxygenで作ったものがありますが、プログラム例が一つも無いので、ぼちぼち整備していこうと思います。今月上旬から中旬にかけてはあまり捗りそうにないですが、一日一例だけでも書き続けていきたい所。でないとまた億劫になりそうで。

SounDecoderやその周りのライブラリ群のメジャーバージョンはまだ0のままですが、XAudio2とかOpenALとかの実装を書き始めて、今の仕様のままで確定できそうになった頃に1に上げたいと思います。それまでは多少の仕様変更は大目に見て下さると幸いです。

概要: また使えなくなっていたウェブログ内検索をそれとなく復旧してみました。

何だか今日はこればっかりやっている気がしますが、ウェブログ内検索が使えなくなっていたので復旧しておきました。以前も似たような問題に遭遇しましたが、今回はText::Balancedとかいうモジュールが無かったようで。MovableTypeのブログ内検索でのエラーというページなどを参考にして何とかなりました。

それで検索はできるようになったんですが、試しにやってみたらスタイルがMinimalist Blue(これ書いてる時点でのこのウェブログのスタイル)じゃない! 背景はすべて白で、文字の大きさにもメリハリが無い。読めない事は無いけど、少し判りにくい。なんというか、スタイルシートのダウンロードに失敗した感じ......。少し調べてみると、他のページとは若干構造が異なる事が判りました。body要素のクラスがlayout-wttではなかったり、他のページでheader系列のクラスが付いているdiv要素にはbanner系列のクラスが付いていました。content系列のクラスはpagebody系列のクラスになっていたり......といった感じで、クラス名が異なる為にスタイルシートがほとんど適用されていなかったのです。

理由は(調べてないので)よく判りませんが、Search Templateが古かったのか、Minimalist BlueがSearch Templateにまともに対応していなかったのでしょう。Minimalist Blueはそれなりに気に入っていたので、Search Templateとユーザ定義スタイルシートに適当に手を加えて、何となく直しました。

検索結果画面は見た感じそれっぽいのですが、これってきちんと直ってるんですかねえ? 一応、使い物にならない事は無いので様子見です。

概要: Movable Typeの「改行を変換する」を改良するプラグインを発見。いい感じなので、沢山のサイトでレビューされてるようですが私的メモ。

以前から、「改行を変換」フォーマットで記事を書くと、変な風にp要素やbr要素が入りまくって嫌で、最近まではそれを使わずに書いていましたが、最近は妥協していました。しかしながらpre要素を使った時の崩れ方が半端でなかったのでどうしようかと思っていた所、「改行を変換する」を改良するプラグイン(MT4.1/4.2対応)なるものを見つけました。

使ってみると、いい感じです。pre要素を使っても、その中にp要素やbr要素を大量にぶち込んだりしません。今度からこれをデフォルトで使うと良さそうです。

以前のバージョンでは、フォーマット名が凄い事になっていた(数値文字参照が展開されなかった)のですが、MT 4.1/4.2対応版では直っているようです。

これでソースコード書いたりするのが楽になりました。あとは、IEがwhite-space : pre-wrap;に対応してくれるといいんですけどねえ......。