お世話になってます。
VC初心者のベッケンバウアーと申します。
以前、ブラウザやドラッグアンドドロップなどを実装する際 COM というものを利用させていただいた
のですが、今更ながら COM って何だろう?と思いいろいろ調べることにしました。
とはいえ本を買う金銭的余裕がないため(本棚もないし)、ネット検索で済ませたいと考えていま
す。
で、ドットコムのURLサイトばっかり引っかかりつつ、いろいろ調べたところ
以下のそれっぽい情報をゲットしました。
・COMとOLEがしばしば同じ物っぽく解説されている(OLEがCOMの古いやつ?)
・ActiveXやOCXと似たようなもの
・VC6.0のプロジェクトのタイプに「ATL COM AppWizard」ってものがある
・WindowsはCOMの塊のようなもの(ということはWindowsのめぼしい機能はCOMを使えば利用でき
る?(APIの代わり?))
・意外と簡単に自分で作れる「ATLプロジェクト」等で。
・Windows Updateなどで勝手にいろいろ追加されてく。
・作ったCOMはVC以外にもVBやWSHでも利用できる。
で、結局はようわからん。という結論にいたりました。
ということで聞きたいことをまとめてみました。
・COMとは?
・ATLとCOMの違い
・COMとOLEの違い
・標準COMの種類や使い方◎
・参考サイトURL
とこんな感じです。
標準COMというのは、例えば
IEコンポーネント
http://www.nitoyon.com/vc/tips/ie_component.htm
Drag & Drop
http://www.yoh.u-tokyo.com/document.php?conffile=trash.conf&page=2
OLEサーバ(ようわからんが
http://www.ujasiri.com/prglib/vc/ole/vc_ole.html
などのことです。(一般的なCOM)
探してもあんまり多く見つけられなかったのですが、たぶんいっぱいあるはず。
自分で調べろという感じかもしれませんが、是非お力をおかしください。
よろしくおねがいします。
まあなんていうか、プログラムのどの部分がCOMなのかようわからないんですよ。
継承して使うようなAPIっぽいものがCOMなんですかね・・・
IEコンポーネントの
CreateWindow( AtlAxWin, Shell.Explorer.2,
の部分はAPI?それともCOM?
ATLみたいにインターフェイス(関数名)にAtlとかついてると調べやすいんですが・・・
この理屈だとAPIも ApiCreateWindow になるか(使いづらいな
C標準関数 std_fopen std_printf とかですかねw
ごめんなさい余談でした。
ちなみに私の普段プログラムしている環境は
WindowsXP
VisualC++2005
PlatformSDK
です、一応。
・COMとは?
Common Object Model。
(OSベンダとして)Microsoftが提唱/提供してる、
主にWindows上でのバイナリモジュール間インターフェイス仕様。
・ATLとCOMの違い
Active Template Library。
(コンパイラベンダとして)Microsoftが提供する、Templateで実装されたクラスライブラリ。
ようは、立場としてはMFCとかと一緒で、Win32アプリを書く際にMFCのライブラリを使うように、
COMを実装する際にはATLを使うと便利だと、そういう謳い文句の、動作の軽いライブラリです。
ATL以外でCOMを実装することもできますし、ATLでCOM以外のアプリを書くこともできます。
・COMとOLEの違い
歴史的経緯などがありますが、OLE2を実現する技術の名前がCOMかと。
(極論、呼び名が変わってちょっとぱわーあぁっぷ)
・標準COMの種類や使い方◎
標準COMというのが何をさしているかわかりませんが、COMのインターフェイスのことですか?
であれば、腐るほど存在しますし、私でも定義できますので全てを把握してる人は存在しないと
思いますし、何をもってして標準というかがわかりません。
使い方は、Windowsとしての一般的な話であれば、CoCreateInstanceとか使って…
という話になります。
VC限定なら、CComPtrとか使うとAddRefとかReleaseとか自動でやってくれるので楽かと。
・参考サイトURL
http://www2.nsknet.or.jp/~azuma/o/o0016.htm
※ぐぐってみただけで、サイトのお勧めはよくわかりません。
> ATL以外でCOMを実装することもできますし、ATLでCOM以外のアプリを書くこともできます。
# 私見:OOとしての設計は、MFCよりATLの方が綺麗だと思う。
あぁ、有名なCOMの例というと、DirectXはほぼ全てCOMベースですね。
DirectXの場合は、Win32API直打ちで、ATLとかMFCとか使わない世界の例が多いですが、
まぁCOM自体はあんな感じで使います。
> まあなんていうか、プログラムのどの部分がCOMなのかようわからないんですよ。
COMインターフェイスを実装する部分、COMインターフェイスを呼び出す部分がCOMなのでは。
参照先サイトの例で言えば、IHTMLDocument2とかがCOMインターフェイスですし、
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/
reference/ifaces/document2/document2.asp
VC付属のCComQIPtrまわりがCOM関係の細かいお約束をいろいろ処理してくれてるCOMの利用部分です
ね。
> 継承して使うようなAPIっぽいものがCOMなんですかね・・・
新しい機能が追加になるときとかは、新しいインターフェイスを切りなおすものですし、
実装継承も許しません。COMインターフェイスってのは、基本的に使う側も継承しないです。
# でないと「継承」という概念がない言語から呼び出すときにつらいですし。
# とはいえ、C++におけるIUnknownの実装は、継承で行われますけど。
> IEコンポーネントの
> CreateWindow( AtlAxWin, Shell.Explorer.2,
> の部分はAPI?それともCOM?
Win32APIを呼んでるだけですね。COMとは直接無関係。
# ちなみに、API:Application Programing Interfaceなので、この観点で言えば、
# ほぼ全てのCOMインターフェイスもAPIの一種ですね。ここではWin32APIを指してるでしょうけ
ど。
> ATLみたいにインターフェイス(関数名)にAtlとかついてると調べやすいんですが・・・
COMのインターフェイス名(C++ではクラスにマッピング)は、慣習として大文字 I で始まります。
関数名はラクダ表記が慣習というくらいで特定の決まりはありませんが、
MFCでもメンバ関数の頭にはAfxとかつけたりはしてないと思いますが…。
> この理屈だとAPIも ApiCreateWindow になるか(使いづらいな
ええ。
> C標準関数 std_fopen std_printf とかですかねw
こちらはC++だとstd::fopenとかstd::printfになってますね。
> # ちなみに、API:Application Programing Interfaceなので、この観点で言えば、
# ちなみに、API:Application Programming Interfaceなので、この観点で言えば、
# typo: 'm'が足りなかった。
いくつか補足。
C++屋さんから見て、別のコンパイラでコンパイルしたクラスのオブジェクトを安全に受け渡して、
生成/破棄/利用できるような仕組み(の一方式)がCOMだ、とか言ってみるテスト。(ちと強引
実行時にモジュールにまたがる場合、普通のDLLだと関数ベースはある程度汎用的に動作しても、
クラスの受け渡しはコンパイラ依存するのですよね。
これを回避する定石(確保したメモリは確保した側で開放しろ)などを呼出部を中心に
ルール化したのがCOMである、と、あえてC++中心の極論で書いてみました。
> ATLみたいにインターフェイス(関数名)にAtlとかついてると調べやすいんですが・・・
誤解してそうな気もするので一応。
ATLのグローバル関数名にAtlと付いてるのは、
MFCのグローバル関数にAfxと付いてるのと大差ない理由です。
# どちらも、VCのバンドルライブラリであることに変わりはない。
で、主要なものには確かにAtlと付いてますが、全部についてるわけではありません。
最近では、MFC7とATL7は一部ソースの統合なども行われていますし、
Atlが付かないATLの構成物とかもあります。(MFCの一部でもあったりするとか…)
Banさん、丁寧に答えしていただきありがとうございます。
非常に助かります。
> Active Template Library。
> (コンパイラベンダとして)Microsoftが提供する、Templateで実装されたクラスライブラリ。
> ようは、立場としてはMFCとかと一緒で、Win32アプリを書く際にMFCのライブラリを使うように、
> COMを実装する際にはATLを使うと便利だと、そういう謳い文句の、動作の軽いライブラリです。
> ATL以外でCOMを実装することもできますし、ATLでCOM以外のアプリを書くこともできます。
Windowsプログラムを楽に行うための支援ライブラリって感じですかね。
今度試に勉強してみまようと思います。
> 標準COMというのが何をさしているかわかりませんが、COMのインターフェイスのことですか?
> であれば、腐るほど存在しますし、私でも定義できますので全てを把握してる人は存在しないと
> 思いますし、何をもってして標準というかがわかりません。
IEやドラッグアンドドロップみたいな機能を備えたCOMが他にもいろいろあると思ってたんです
が、標準って概念がないんですかね・・・・
WindowsはCOMの塊のようなものらしいので、いろいろあると思ってたのですが。
Windowsをインストールした時点で必ず備わっているCOMって言い方だとどうでしょう?
フォルダを見るエクスプローラとか、ファイルを開くダイアログとか、(ってコモンダイアログか^
^;)
> あぁ、有名なCOMの例というと、DirectXはほぼ全てCOMベースですね。
聞いたことあるかも。
そういえば、DirectXランタイムってWindowsのバージョンによっては入ってたり入ってなかったり
マチマチですよね・・・・
そう考えると先に述べた Windowsをインストールした時点で必ず備わっているCOM ってのも曖昧な感
じですね。
そういえばIHTMLDocument2も IEの4.0だか以上のバージョンがインストールされてないと使えない
らしいですし、これもWindows標準とは言いがたいですね・・・
うーん・・・・
標準COMが何たらという質問は忘れてください(今更w
> これを回避する定石(確保したメモリは確保した側で開放しろ)などを呼出部を中心に
> ルール化したのがCOMである、と、あえてC++中心の極論で書いてみました。
CComQIPtrとか使って違和感たっぷりなことしないといけないのは、この辺の事情のせいなんです
ね・・・・
なるほど。
いろいろありがとうございました。
・・・それにしてもMSDNのサイト重いな。
COMと呼んでるもの自体は基礎技術というか方式のようなものだと思いますので、
標準といわれるとやはり難しいかと。
COMインターフェイスは、GUID管理ですから、いくらでも新規作成できます。
あえて標準というならMicrosoft(orサードパーティ)が定義したインターフェイスなのかな、
という気はしますが、それも続々追加されますし(新しいDirectXとかが一例)、
同じインターフェイスで別コンポーネントなんて普通ですし。
あくまで「インターフェイスの規定」ですから、インターフェイスを満たす限り、
実装は問わないので。
COMコンポーネントの方が標準というイメージが存在できそうに思いますが、
IEコンポーネントしかり、DirectXの各コンポーネントしかり。
でも、COMコンポーネントって動的に追加できるのも旨みのひとつなので、
やっぱり標準というとMicrosoft(orサードパーティ)が提供してるコンポーネントでしょうか。
自作のコンポーネントがいくらでも作れるもの一緒ですが。
> CComQIPtrとか使って違和感たっぷりなことしないといけないのは、この辺の事情のせいなんです
ね・・・・
Javaとかかかれてたことがあるなら、COMインターフェイスってのは、かなりinterfaceに近いと思
います。
まぁ同じような概念だから、インターフェイスと呼ぶわけでしょうし、
インターフェイスと実装の分離ってのは、設計上でも叫ばれていることですし。
COMが提供するのは、Javaで言えばクラスのローダ部分とかで、
各COMコンポーネントはfactory相当を提供し、COMのAPIから制御してもらう。
使う側は、実装を知らず/問わずに、インターフェイスのみを通じてやり取りする。
COMインターフェイスを取得すれば、規定のメソッドが使えるようになるわけですが、
ガベコレがない言語等でも参照管理をするためのルールなどが決まってますので、
C++側でもそれを遵守しなければならない。これやってくれるのがCCom...Ptrとかです。
どの辺りに「違和感」があるのかは個人の感覚なのでわかりませんが…
個人的には戻りがHRESULTに統一されてるのが…まぁ、例外とか返せないので、
安全なエラー通知を統一して行うには、直接の値返しを戻り値ではやりにくいですね。
戻り値では言語上、オーバロードもできませんし。
まああれです、
COMがコモンダイアログ等、既に実装されている便利なライブラリである、と最初に勘違いしてしまっ
たのが悪かったですね。
頭の硬さ故に最初の先入観から抜け出せず、屁理屈ばっかり言う困った奴ってたまにいますよ
ね・・・・(いっしょに仕事したくないタイプ(ぇ)
危うくそんな奴になりかけてたかも。
> 違和感たっぷり
訂正
若干の違和感○
まあ、C言語からC++に移行したばかりの人みたいなもんですかね。
ちなみにShell APIとかのSHGetMallocもちょっと苦手です。
WinMain引数長すぎ by コンソール派
みたいな。
慣れですな。
礼を忘れたぜ
<b>ア</b>ザース m(__)m
> 歴史的経緯などがありますが、OLE2を実現する技術の名前がCOMかと。
今は(と言っても OLE は既に過去の技術でしょうが…)OLE2 って言わないんですよ
ね。
OLE1 は COM の上に構築されていなかったため、拡張性に乏しかった。
しかし、OLE2 は拡張性が高いため、OLE3 というバージョンが出ることは決してありえ
ない。そのようにバージョンナンバーを区切ることなく、継続的に常に発展していくこ
とができるからだ…とは「Inside OLE」の弁(この本の初版は「Inside OLE2」というタ
イトルでしたが、新版からは「2」が取れました)。
そのため、殊更に OLE1 と対比する場合を除いて(今回はこの場合ですが)、OLE2 では
なく、単に OLE と呼びますね。
#とか何とか言っておいて、.NET に潰されちゃいましたけど。
というわけで、OLE は COM を応用した技術です。
#ちなみに、OLE は一応「Object Linking and Embedding」の略と言うことになってい
ますが、これが通用するのは OLE1 の時代の話です。
#OLE1 は「オブジェクトのリンクと埋め込み」が全てでしたが、2 ではこれに捉われな
くなっていますから。
> C++屋さんから見て、別のコンパイラでコンパイルしたクラスのオブジェクトを安全に
受け渡して、
> 生成/破棄/利用できるような仕組み(の一方式)がCOMだ、とか言ってみるテスト。(ち
と強引
これに賛成。だから最近、COM が大好きになってきています。
C++/CLI で COM を実装するという、時代の流れに真っ向歯向かうような挑戦を企画中。
>> 継承して使うようなAPIっぽいものがCOMなんですかね・・・
> 新しい機能が追加になるときとかは、新しいインターフェイスを切りなおすものです
し、
> 実装継承も許しません。COMインターフェイスってのは、基本的に使う側も継承しない
です。
> # でないと「継承」という概念がない言語から呼び出すときにつらいですし。
> # とはいえ、C++におけるIUnknownの実装は、継承で行われますけど。
継承には、インターフェイス継承と実装継承があります。
COM では、インターフェイス継承は使いまくられていますね。
実装継承は滅多に使われませんが、ないことはありません。「集約」というマニアック
な技術があります。知る必要があるほどメジャーなものではありませんけれど。
なお、「オブジェクト指向」と「オブジェクト指向言語」は同一視するべきものではな
く、その点で言えば、「オブジェクト指向における継承という抽象的な概念」と「特定
のオブジェクト指向言語(例えば C++)における継承という機能」はまた別のもので
す。
COM を使う上では C++ 流儀の継承は通用しませんが、COM には COM 流の継承がありま
す。
> あぁ、有名なCOMの例というと、DirectXはほぼ全てCOMベースですね。
DirectShow のとあるコンポーネントは、IUnknown の規約を破った実装をしてやがりま
した(DirectShow が DirectX ファミリーかどうかは置いといて)。
> 個人的には戻りがHRESULTに統一されてるのが…まぁ、例外とか返せないので、
throw でポイ、ってわけには行きませんが、一応、IErrorInfo を実装するオブジェクト
を「COM 例外オブジェクト」と呼びます。
> まあ、C言語からC++に移行したばかりの人みたいなもんですかね。
そこで、どれだけ「オブジェクト指向」色に染まれるかどうかですね。
COM ってのは、言語やコンパイラに依存しないでオブジェクト指向を実現するためのル
ールの集合体ですから。
そうそう。
COM の標準インターフェイスの使い方なんかに関しては、このサイト(らららのプログ
ラマーズラウンジ)と相互リンクされている、「COM総合研究所」というところがありま
すよ。
http://www5.plala.or.jp/atata/
> throw でポイ、ってわけには行きませんが、一応、IErrorInfo を実装する
> オブジェクトを「COM 例外オブジェクト」と呼びます。
あぁ、ここではthrowでポイ、をさして例外と言ってました。
IErrorInfo…あったなぁ。
とりあえず MSDN のページを紹介してみる
(といっても既に調べている気もしますが……)
Dr. GUI
http://msdn.microsoft.com/library/ja/default.asp?
url=/library/ja/jpdnguion/htm/drgui082399.asp
COM プログラミングの基本
http://www.microsoft.com/japan/msdn/thisweek/combasics/combasics1.asp
# 番外編
COM/COM+ セキュリティ(前半は Windows のセキュリティの話で埋め尽くされてますが)
http://www.microsoft.com/japan/msdn/thisweek/comsecurity/comsecurity1.asp
For a technical discussion of using COM components from .NET see
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/dndotnet/html/callcomcomp.asp
ちょw
返答多くてうれしすぎるw
でも、時間がなくて・・・・
今日は読むだけで精一杯です。(いや本当は単に眠いだけorz)
なにやら小難しい話になってきてる気も
ところで、COMの呼び方はコムでいいのでしょうか?(それだと.comと被るか?)
初心者はそういうところが結構気になるんですよね(私だけ?)
そういえば標準の話ですが、関数にも標準関数って言葉ありますよね?
関数自体はプログラムを小分けしたり再利用したりするものですが、それでも一応コンパイラがある
時点ですでに使えるC標準関数がありますし、Windowsがある時点ですでに使える関数的な感じ。
今日たまたま知ったんですが、FileSystemObject っていうファイル操作するCOMがあるとかないと
か。(COMじゃない?)
VBやらRubyやらWHSなどいろんな言語で使えてるみたいな感じです(軽く検索したみた)
インターフェイスがどうとかいう話はいまだよくわかってないんですが、WHSだと
WScript.CreateObject(Scripting.FileSystemObject)
で取得できるオブジェクトです。
これがCOMだとすれば、こんなのが標準では?
と思ってみたり。
シャノンさん Banさん porinさんごサイトのご紹介ありがとうございました。
今後COMを理解するための参考にさせていただきます。