COMその1

しばらく続く予定。

えーと、いろいろと事情がありまして、なぜかCOMのコンポーネント(?)を作ることになったんですよ。VBで作るのはやったことがありますけど、C++で作るのは初めてなんです。

先週末くらいにちょっと時間があったんで、Webをちょろっと検索してみたんですが、情報がなにも見つからない。DLLの作成法はわかるんだけど、COMにしたいのよ、俺は。しかたがないので、自宅にある本のなかでそれっぽい内容が書いてありそうなやつを探してみる。あったのはこれ。

いつ買ったんだろ、こんな本。あ、とりあえず張ってみるだけで、お勧めはしません。つまんないし。んでまあ、読んだ記憶がまったくないんだけど、ざっくり眺めてみると、どうやらVisual C++でATLなんちゃらというプロジェクトを作ればいいとか書いてある。とりあえず起動して作ってみたんだけど、よくわからなかったので、さくっと諦めた。

ここまでが先週末。

まあいい。Webに情報がなくても、本がなくても、俺にはMSDNがあるじゃないか。Visual Studio 6.0に付いてたやつだから、アップデートで消えたりしてない。そういうわけでATLというキーワードだけは覚えていたので、読んでみる。「ATL(Active Template Library)リファレンス」。どうやら、GUIがあってけっこうよきにはからってくれるみたい。Microsoftやるじゃないか。

Testとかプロジェクトを作って、Test1とかまたやるきのないクラスを作る。メソッドを追加、と。ここで問題。メソッドの返り値ってどうやるの?HRESULTってなに???困ったときは、VBを起動(笑)。とりあえず引数になにも書かずにメソッドを追加して、コンパイルして、VBを起動して、参照を追加して、F2で眺めてみる。Subになってる。でまあ、MSDNを眺めたりしてるうちにPropertyに気づいて、そしたら[out, retval]とか引数に書いてあったので、書いてみたらうまくいきました。

中略。

オブジェクトを返したい場合は、[out, retval] IDispatch** retとか書けばいいみたい。でも、オブジェクトはどうやって設定するんだ?とりあえずret = NULL;とかしてみたら、Nothingが返ってきた。なるほど。ちなみに何も設定しないで実行してみたら、VBが落ちた。でも、俺はTest1のインスタンスを作って返したいのだ。とりあえずnewしてみたが、コンパイラおばちゃんに怒られる(さすがにCTest1.newとは書かなんだ)。あれか、スマートポインタとかのからみで、なんかファクトリがあるのか。よく見るとCreateInstanceとかいうメソッドがあるので、これっぽいということで検討をつける。

STDMETHODIMP CTest2::NewTest1(ITest1** ret)
{
	// TODO: この位置にインプリメント用のコードを追加してください
        CTest1.CreateInstance(ret);
	return S_OK;
}

これでどうだ。*1


コンパイルエラー。なーぜーだーーーーーー。




あ、CTest1::CreateInstance(ret)でしたか。そうでしたか。そうだったような気も。おじさんもうC++6年くらい、ひとっっっっっつも触ってなかったから忘れちゃったよ。ごめんごめん。

::ってなんだっけ?

namespace、じゃねえよなぁ、CTest1は。

*1:ちなみに、IDispatch**をITest1**に変えてみたら、ちゃんとVBから返り値がTest1になって幸せになれた。