Contents

Monologue

is not a blog.

DICE

IRC/Webサーバ for MS Windows®

Essays

プログラミングに関する文書他

English Side

英語コンテンツ

 

Favorites

Beyond3D

The forum runs @ 120fps.

Slashdot

News for nerds, stuff that doesn't matter - powered by Slash

The Code Project

Windows Free Source Code and Tutorials

SceneCritique

Powered by DICE

The Old New Thing

For all Windows programmers

Links

Home

Home (alt.)

Essays

 

[2008-02-11] WindowsにおけるC++へのPHP組み込み環境の構築

前回の記事では、PerlとRubyのC/C++コードへの組み込みを扱った。DICEへの組み込みの評価を兼ねていて、当時はPerlを使うことになった。一方で、DICEのwebサーバとしての側面をもっと強調せねばという課題が以降わりと念頭にあり、webサーバを名乗るからには現在のweb向けスクリプト言語No1としてのPHPをサポートしていないというのはいかにも心苦しい。海外では、VBulletinやWordPressが利用できてようやくそれなりのwebサーバとしてユーザの検討の俎上に載せられることもあるだろう。このPHP組み込みに関する取り組みの際にいくつか問題に遭遇したので、それらについて記録。

 

[2007-12-22] SSL Server with OpenSSL Memory BIO a.k.a. Prerequisite to Asynchronous OpenSSL (英語)

前回のSSLに関する記事では、DICEでSSLを扱うために、WindowsのAPIであるところのSSPI (Security Support Provider Interface)を利用したと書いた。ところが、HTTPSを実装したDICEの最新バージョンではOpenSSLを使うように変更した。変更の理由と、非同期ソケットによるSSLサーバを書くのに必要な基礎であるmemory BIOの解説とを本記事として載せた。

 

[2007-12-22] C++ Asynchronous Delegate for Microsoft Windows (英語)

WindowsはQueueUserWorkItemという非同期関数呼び出しのために有用なAPIを備えている。この関数と、Windowsが何をやっているか把握しているスレッドプールによって、非同期関数呼び出しの面倒が随分軽減されている。しかし、外部のC++オブジェクトのメンバ関数を非同期に呼び出すためにコンテクストを設定する必要が出てくると、結構手間であることには変わりない。本記事ではC++テンプレートを使ってAsyncDelegate.hなるツールを作ることでこの問題に対処する。

 

[2007-01-11] はてなwebサービスAPIを用いたPerl/Ruby webアプリケーション2題

はてな」の認証webサービスAPIと、キーワードwebサービスAPIを利用した、2つのwebアプリケーションを作成する。1つ目のwebアプリケーションは、「はてな」認証APIを利用した、「はてな」ユーザが特定の他ユーザに外部サーバを介して任意のデータファイルを渡すためのファイルアップローダである。言語はRubyで、RubyのwebサーバMongrelのモジュールとして書かれている。もう1つのwebアプリケーションは、オープンソース形態素解析エンジンMeCabと「はてなキーワード」APIとを利用した穴埋めクイズ作成と、「はてなキーワード」連想グラフのJSVizによる視覚化を行う。言語はPerlで、PerlのwebサーバPOE::Component::Server::HTTPのモジュールとして書かれている。

 

[2006-11-15] Perl, Ruby, Multithreading, Embedding (英語)

前半はスクリプト言語PerlとRubyによるマルチスレッドプログラミングについて、webから多数のファイルをまとめてダウンロードするスクリプトを注釈する。IrvineというWindows用のダウンロードマネージャがあり、便利なので使い続けていたところ、chunked transferへの対応が中途半端なままこのアプリケーションが更新停止しているため、正常にダウンロードできないサーバに最近当たった。そこでアジャイルソフトウェア開発とばかりにPerlでアドホックな代替ツールを書き、ついでにRubyへ移植した。後半は、PerlとRubyのC/C++アプリケーションへの組み込みについて解説する。久々のDICE更新に際し、折角なのでもう一つ新機能を付けようということになりwebサーバ部分へのスクリプト言語のインタプリタ組み込みを選んだ。2年前にDICEへ組み込み済だったCLRでは既存のwebアプリケーションがそのまま実行できないので、今回は、ネットで配布されている既存のwebアプリケーション、具体的にはCGIを、mod_perl同様にオンメモリで駆動するのが目的である。PerlのCGIなんてPHPが人気の今時古いかなとも思ったがMovableTypeなどは今でもPerlを使用しているらしい。CLRは万能で、AppDomain等の概念やCOMのおかげでC++コードへの組み込みの相性も完璧だが、インターフェイスを独自の物しか用意できなかったので.NETのコーディングが出来ないユーザには無縁の代物になっていた。今回は結果的にDICEへPerlを組み込んだので、サンプル然としたRuby組み込み編に対し、Perl編はDICEに使用した実用的なコード(Perlのヘルパースクリプト)を記事中に掲載してある。実際の動作はDICEをダウンロードして確かめてみて欲しい。

今でも簡単な作業にはPerlを使用している。Perlは、今回のようにシンボルテーブルを操作してリフレクション/イントロスペクションをやることでプラグインシステムを実現するような特殊なことをやるにはグルー言語としての面目躍如で良いのかも知れないが通常のコードでもその類のシンボルテーブルの実装に依存した汚いハックが高等な動的言語向けテクニックであるかのようにユーザに推奨されているとすれば不健全である。それよりは、広く知られているソフトウェア工学上のパラダイムが簡単に利用できる形で提供されているという状態の方が風通しがよい。何故RubyがDICEの組み込みから落選したかは些細な理由による。実際、このページの下の方の、Perlで書かれているDiablo en Laberinto迷路CGIの紹介の項で、約5年前にRubyについて述べた批判的な感想は、Rubyの本質的な特徴を攻撃しているのでやすやすと消えはしないものの、本文中では批判色はかなり薄まっている。むしろ、Ruby万歳というくらいの記事かもしれない。もう後一歩の所で問題が発生しなければPerlではなくRubyの方を組み込みに選んでいたと思う。特にRubyが好きでもない自分のような人間も使用を考慮せざるをえないところまでRubyは躍進してきた。それよりも、5年前に自分が書いたことを読んでみて可笑しかったのは、Perl 6が現時点でまだリリースされていないということだ。

 

[2006-11-12] サーバプッシュの現在 - AJAXの辺縁

DICEに添付したIRCクライアントwebアプリケーションのソースに注釈を加えつつ、プッシュテクノロジの現状を考える。DICEのIRCクライアントwebアプリケーションはJavaScriptによるDOMプログラミングとソケット通信バックエンドを担うFlash 9(ActionScript 3.0)の協調によって成り立っている。タイムリーなことにTamarin Projectが発表されたのでそれと絡めた話も冒頭に書いた。Comet/Streaming HTTPと言われる古風な手法とそれと対になるwebサーバに飽き足らない人向け。「AJAXを超えて」というタイトルにしようと最初は思ったけれどDICE自体が反則技なアプリケーションで飛び道具的な所があるのでそれでAJAXを超えたと称するのはフェアじゃないなと思い直し穏当なタイトルにした。

 

[2006-11-09] C++ and C#/.NET Interoperability for RSA Public-key Cryptography and AES Symmetric Cipher (英語)

何年か前にC#とC++でとあるクライアントとサーバ(多分C#の方がクライアント)を作ろうと思っていた時に、RSA公開鍵暗号とAES対称暗号(Rijndael)がC#サイドのライブラリ(.NET Framework)とC++サイドのライブラリ(Crypto++)で相互に動作するか試験するために作ったコードの解説。簡単な鍵交換を実装している。これより前に作ったDICEの管理用クライアントの独自プロトコルはこれを踏襲しているが、C#の方のコードは使う機会のないままになってしまったのでここでC++/C#双方のテストコードを記事にして公開。

 

[2005-05-05] How to Programmatically Create Self-signed Certificate and Key Pair Association for SSL Communication with Microsoft Windows SSPI (英語)

Windows上でプラットフォームSDKのみを利用して、自己署名済みSSL証明書を生成し、公開/秘密キーペアと関連付けた状態で証明書ストアに収める方法の解説。SSPIによるSSL通信のためにはメッセージの復号に必要な秘密キーが証明書と関連付けられた状態で取り出せるようでなければならない。実際のコードを求めるまでの導入の中で、デバッガ(OllyDbg)による簡単な関数呼び出しの捕捉についてもあわせて解説している。

 

[2003-08-16] Template Metaprogramming for Dummies

近年のC++言語の醍醐味といえば、間違いなくテンプレートである。テンプレートがあるからこそ、凡百の強い型付けのオブジェクト指向言語から屹立したC++の存在がある。そのテンプレートを用いて、コンパイル時にコンパイラに計算を実行させようというテクニックがテンプレートメタプログラミングである。ただし一般的な手続き指向やオブジェクト指向とは異質な点があるためしばしばこのテクニックの参照元とされるLisp言語と同じく、敷居が高く他から隔絶したトピックであるかのように一見思える。こうした先入観を改め、この有用なテクニックを習得するためにも、ここではC++におけるテンプレートメタプログラミングの基礎的イディオムを浚いその必要性を理解しつつ断絶を埋めた上で、このテクニックの限界を示す。例として、ビットフラグの表現と、ガロアフィールド計算表(の一部)を、テンプレートによって静的に生成する。

DICEのコードを整理して汎用サーバのパターンとツールキットライブラリを抽出しようとしたとき、例えばサーバクラスとクライアントクラスの相互参照の解消や、マルチプロトコルのテンプレートポリシー/パラメータ化、アブストラクトファクトリのセッションプールへの応用など、Lokiライブラリが大いに役立ったので、Lokiで活用されているジェネリックプログラミングのテクニックに関心を持つようになり、それに合わせテンプレートメタプログラミングについて学習した事柄を一貫した文章に整理したもの。ただし、genericsの実際の利用に関しては、code bloatの問題やソースが読み難くなる場合もあるので、この記事を書いた後急速に意欲を失ってしまった。テンプレートや静的結合は使用が最も適切な場所にのみ使うべきであり、本末転倒にならないよう注意すべきである。個人的にこの記事を書いたあたりが、プログラミング言語について、単なるツールに対して持ちうる以上の興味を持っていた最後の時期だったという気がする。

 

[2002-11-22] Windows C++ マルチスレッドアプリケーションデバッグ法

Unmanagedマルチスレッドアプリケーションデバッグ法であり、さらにWindowsマルチスレッドアプリケーション実装テクニックであり、そしてWindowsアプリケーションデバッグ法でもある、一粒で三回美味しいテクスト。だと思う。特に大規模サーバアプリケーション向け。

 

[2002-12-21] KLassphere Athens (バイナリのみ, zipアーカイブ)

Microsoft IISで動かすISAPIのWeb掲示板プログラム。Microsoft SQL ServerまたはMSDEに記事を保存する。投稿時にはセッションに対しJPEG画像を生成し画像の数字を投稿者に読ませて自動投稿を防ぐ。画像にはぼかしや回転などのエフェクトをかけることができる。掲示板の構造はディレクトリ型になっており、記事の連続(いわゆるスレッド)をXMLのノード構造と同じく無限に下方へ延ばしたり分岐させたりすることができる。個々のノードはルートノードのデザイン属性を継承し、ルートノードに適用できるデザイン属性(テーマと呼ぶ)はXMLの設定ファイル内に複数用意できる。

以前作って配布していたC++のCGI掲示板(こちらはBabylonという名前で、Unix向けに書いた)の部品とDICEの部品とを再利用して2001年末から2002年の正月にかけて短期で作成。2002年はDICEにかかりきりだったのでようやく年末に日の目を見ることになった。ISAPIとはMicrosoftのwebサーバIISにロード可能なコンパイル済アプリケーションモジュールである(IIS以外にもISAPIをホストできるHTTPサーバはいくつかある)。AthensはC++のISAPIなのでこの種のWebアプリケーションとしては最速で動作するものの万人向けではなく、日に何万ヒットかある場所でなければ使う意味はない。データベースサーバとはOLE DBというCOMのAPIで通信する。本当はディレクトリ内でノードを移動するAPIなどを実装すべきだがその前に力尽きお蔵入りになった。

 

[2002-11-05] DICE Technical Notes II

DICEバージョン0.1リリースに際しての、設計と実装に関する覚え書きの第2回。VirtualDirectoryの詳細を記述した。ほかWindows 2000以降でのサーバアプリケーション設計についての意見など。長ったらしいので暇な人&好事家&妄想癖のある人向け。

 

[2002-04-04] Early DICE Design Notes (英語)

DICEの製作を始めるに当たっての設計に関する覚え書きの第1回。IRCを取り巻く現在の状況と、なぜUnixではなくWindowsでサーバを作ろうと思ったのかについて。

 

[2001-xx-xx] ComponentID

Win32のUUID(GUID)構造体のラッパークラス。VS.NET2003付属STLのhashコンテナ(hash_map/hash_set/hash_multimap/hash_multiset)用比較関数、SGI系STLのhashコンテナ用ハッシュ関数オブジェクト付き。システムの用意した構造体を継承してクラスを作るというのは割とよくやる方法で、継承した場合vtableが無ければメモリレイアウトの先頭に継承元が入るので、後ろに追加のデータをペイロードとして付けた上で、親の構造体を引数とするAPIの引数に使えるという利点がある。換言すれば、templateと、template policyを利用したmix-inによって、C++における継承は、Java等のクラスライブラリに顕著な、現実世界やデザインパターンとして観念されるモデルのマッピングに近いカテゴリ概念の素朴な具体化のための道具というよりは、本来の意味でのデータ抽象/アルゴリズム抽象に向けての手段として、あるいはCOMのバイナリ仕様の表現として活用(exploit)される箇所しか出る幕が無くなってしまった。

 

[2000-xx-xx] RijnDael Cipher Wrapper (バイナリのみ、zipアーカイブ)

Rijndaelという、 AES (Advanced Encryption Standard - DESの後継)に選出された暗号アルゴリズムがある。そのリファレンス実装ではないCの実装からC++のクラスを作り、CBC等のモードを追加した上でWindowsコンソール用のファイル暗号化プログラムとしたもの。Cの実装がマクロを使っているところをテンプレートを使って書き直したりしてC++の練習にした覚えがある。当時クロスプラットフォームや標準C++に傾倒していたのでC++のiostreamを使った。その為ファイル書き出し部分が非常に遅い。iostreamは遅いというのは定説で、C++に関するテクニックの解説書であるEffective C++ではC++の新機能に馴染むためにiostreamの多用を勧めているのが、続編More Effective C++ では速度重視の場合はCライブラリで済ませろとされているのが笑える。UnixでもWindowsでもメモリマッピングのAPIがあり、暗号化後のファイルサイズ計算は容易なので、それを使用すべきである。ただしMS Windowsに限るならば、 ディスクへのシーケンシャルアクセスの効率性が物を言う箇所では素直にCreateFile系のAPIを使用するのが速度上最も有利になる場合すらある。

 

[1999-xx-xx] Diablo en Laberinto

昔のPCゲームWizardryに似せて作ったワイアフレームの3D迷路を抜けてゴールまで行くと掲示板に入れるというキッチュな構成のPerl CGIスクリプト(GPLed)。一時期、慣れると動くプログラムが魔法のように速く書けてしまうのでPerlに熱狂していた。Perl5のオブジェクト指向を中途半端に取り入れてみてはいるものの、実態は巨大なフローの関数を適当に束ねたいかにもC的なものに終わっている。実際プログラムの部分より迷路のワイアーフレームのアスキーアートを書く手作業の方が遙かに時間がかかってしまった。モンスターのアスキーアートはさすがに画像から機械的に取り込んでいる。アスキーアートにしてもShift_JISの文字を使ってはASCIIではないのでASCIIのみで表現している。迷路のデータはテキストエディタで編集できるが、それでも面倒なのでビジュアルな迷路マッピングを行ってくれる便利なWindowsのツールがないかと探したところ実際にあったので、そのツールの形式からインポートするCGIも付けた。

迷路の仕様、たとえば一方通行の壁であったりダークゾーンであったりという部分はWizardryを模しているものの、Wizardryの肝であるキャラクタシステムは欠落している。ドラゴンクエストというゲームには"ふっかつのじゅもん"なる名称でキャラクタの属性をセーブする文字列があったが同様にQUERY_STRINGの部分にプレイヤーのデータが暗号化されて入っているのでサーバ側にプレイヤーのデータは保存されず各セッションはあくまでステートレスである。キャラクタシステムや戦闘システムをも付けようという奇特な方はGPLなので勝手に再配布して欲しい。

掲示板部分は特筆すべき箇所はない。デザインをツリー状のスレッド表示と一本のゲストブック表示とに切り替えられる。また、JavaScriptによる投稿文暗号化/復号化スクリプトも添付してある。

この掲示板を書いた後、2000年頃に、掲示板型Webアプリケーションを抽象化するというコンセプトに取り憑かれ、C++でUnix/Windows双方で利用できるCGIを作って、一時期配布していた。掲示板デザインを表現するためのスクリプトを起動の度に読み込むという苦肉の策によるもので、ネイティブコンパイルされているので速度は何とかなるだろうと思ってそのようにした。また、連続投稿を防ぐために、数字を描いたJPEG画像を生成する。掲示板プログラム作成にあたっては、各々の記事のシーケンスはIteratorパターンであるし、それをiterateしながらHTML(あるいはXMLでもCSVでも何でもよろしい)へのレンダリングを行うためにVisitorパターンを応用すればよい。記事保存ファイルからde-serializeした生のバイナリを動的に各々のクラスに関連づけるための仕組みも作ってやる必要があるだろう。最終的には、パフォーマンスと信頼性を保持しながら掲示板記事のスレッドツリーをマップできるデータ構造を表現するために、資料の豊富なOS/2のファイルシステムHPFSを参考として、記事保存ファイルを、B-treeとビットマップインデックスを備えた仮想ファイルシステムの形式とした。B-treeがディレクトリ内のファイルのリストを表現し、それをさらにツリー上にリンクすることで掲示板のデータ構造を表現する。その部分は完成したものの、最後の瑣末な仕上げを行う段階でDICEの開発に入ったので、こちらの方は放棄されることになった。Windowsの他に、わざわざLinuxとFreeBSDの環境を作ってビルドしていたので手間が厭わしくなったということもある。デュアルブート環境が原因で何十GBものデータが飛びそうになったこともあり(パーティションテーブルの一部がWindowsからアクセスできない状態になり、何故かDOSからは正常にアクセスできたので、DMAの効かない状況下で何時間もかけてファイルを別のSCSIのHDDへ転送して退避しなければならなかった)、とにかく危ない橋は渡るべきでないという教訓になった。

Perl 6のリリースが非常に遅れ、またRubyのような"human"な言語に対抗してか、妙に自然言語の英単語がPerl 6に取り入れられるようになってきたので新しいPerlには幻滅してしまった。C#も若干そんなところがありプログラミング言語として美しくないと感じる。一方、スクリプト言語のRubyは、VHLL(Very High Level Language)と呼ばれたり、機械指向ではない人間指向の言語として推されたりするが、単一の言語そのものを指して人間指向と称するのはミスリーディングである。人間は単純ではない。機械的思考を行う人間も存在するはずである。複数の作法が選択可能な状態を人間指向とするなら賛成の余地もある。私はPascal式のbegin - endが嫌いでC式の括弧が好きなのでRubyの文法が置換可能ならそれに優る物はないと思う。その意味で、.NETやParrotのようなバックグラウンド技術の方へ今は目が向いてしまう。

ちなみに、配給がSirtechの倒産騒ぎで数年遅れたWizardry 8は、勢い込んで始め、キャラクタメイキングは興奮しながら行ったにもかかわらず、数年前のバージョンのMight & Magicかと思うようなゲーム本編の古臭いインターフェイスに幻滅し、開始後20分で放棄した。英語版の場合、デモでもないのにパソコン屋のCMが入る駄目っぷりが落胆に追い打ちをかけてくれた。ここ数年RPGは時間がないのも手伝い大概こんな調子でやりすごしている。やっぱFPSでしょ、FPS。