トップページ⇒tech
986コメント350KB

COM の世界を斬る!

■ このスレッドは過去ログ倉庫に格納されています
0001IUnknownNGNG
ATL や MFC でラッピングされていない素顔の COM について語り合いましょう。
0413デフォルトの名無しさんNGNG
COM関係のスレ2つとも職人さんたち対象なので、
お勉強レベルのスレがあってもいいかもね
0414409NGNG
>>412

1 そんなことできるわけねーだろ、ボケ
2 そんな簡単に実現できること、自分で調べろ ゴルァ

なのか、どっちなんでしょう?
それだけでもよろしくお願いします。
0415409NGNG
通常ポインタがプロセスを超えられないことは知ってます。
ただ、スタックトレースを見ると、たとえばドラッグ&ドロップなんかは
rpcrt4.dllなどを介してcallされているし、何か抜け道なりがあるのかもしれないと思って聞きました。

ちなみに、フックをかけてcallをする方法は試してみたところ成功しました。
0416デフォルトの名無しさんNGNG
>415
だから、マーシャリング、プロキシ/スタブ、スレッドモデルなんかに
ついてもっと勉強しろや。
他のプロセスにあるinProc COMサーバを(その、「ほかの
プロセス」を実行主体として)呼ぶのは、フックでもしないと無理。
そうでないなら、普通にCreateProcessから呼び出せば、
あとはole関連ライブラリが善処してくれる。
0417406NGNG
>>408
バインド方法とサーバのプロセス形態は直接は関係ないですよ。
バインド方法はVBのソースで型名でオブジェクトを扱うのか、
Objectで扱うのかの違いでしょ。
一般的にVBでいうところのバインドは、

参照を追加して型名で操作 == アーリーバインド
 開発時に型情報等を解析する
  サーバへのバージョン依存性は高くなるが
  開発時にエラーチェックできる
  またパフォーマンスはよい
object型で操作 == レイトバインド
 実行時に型情報等を解析する
  サーバへのバージョン依存性は低くなるが
  実行時エラーになる可能性もある
  またパフォーマンスはさがる

という事で >>396 でなぜレイトバインドが一番速かったのか
と疑問に思っているのではないでしょうか。
#ちなみにnewとCreateObjectはオブジェクトを作るときのみ
#違いがあるので受けた後の型しだいで上記と同じ。

バインド方法で著しくパフォーマンスがかわるのは
dualインターフェイスのインプロセスサーバを扱った
ときでしょう。アーリーバインドで開発時にIUnknown側の
メンバーを扱う様にコードが吐かれるのか、レイトバインド
で実行時にDispatchのInvoke経由でメンバーを扱うのかという。

たとえdualインターフェイスでもアパートメントに互換性が
あるインプロセスサーバ以外は直接サーバとは対話していない
ので注意が必要です。

しかし >>396 で検証した結果レイトバインドが速いというので
あれば、仮説ですがVBがDispatchのみのエクセルに対して
アーリーバインドするとエクセルを扱う仮想のエクセルオブジェクト
を作成しているとか、使用しないメンバー情報等も全て
取得してまうとか...そのぐらいでしょか。

結局エクセルを扱うときDispatchでInvokeするしかないわけだから
アーリーバインドする事でどのぐらいパフォーマンスに差がある
かといわれると「誤差ぐらい」と思われますが。
0418ななしNGNG
>>417

丁寧なコメント、ありがとうございます。m(_ _)m
残念ながら、私は勉強不足のようです。(VBユーザーは、COMを「使う」ことはあっても、
内部の仕組みは必ずしもしらなくても足りてしまう場合が多いので)

このスレの話題について行けるよう、いろいろ研究してみます。
ソフトウェアの動作原理や(隠蔽された)内部のふるまいに興味が大いにありますので。
0419DNGNG
Inside COM+ や Inside OLE ぐらいは読んどいたら?
0420デフォルトの名無しさんNGNG
>>419
たしか前者は入手困難じゃなかった? 
0421DNGNG
それは後者だね。ちなみに私は 177 のレスを読んで
速攻買いに行きました。ここまで高い本買ったのは初めてだったが
かなり勉強になるよ。入手出来なければ大きめの図書館で借りたりとかね。
家の近郊の図書館にはInside OLEはあった。まあ購入後知ったことだから
どうでもいいんだけどね。常に手元に無いと落ち着かないって言うのもあるし
損した気分にはならなかったね。今の学生さんならお金持ってるだろうし
そんなに負担ではないのでは?(いいかげんな推測ですが)
0422ななしNGNG
>>421

いちおう、ええ歳こいた社会人(0x20代)なので(にしては、厨房質問ですが(^-^;;;)、
本くらいは買えます。

「Inside COM+」ですね。
ありがとうございました。m(_ _)m
0423デフォルトの名無しさんNGNG
InsideOLEは駒場東大前の駅前の書店に野ざらしにされてボロボロの状態で、定価で売ってる。
俺が立ち読みしてるので、絶対に買うな。お長居します。
0424ななしNGNG
>>423
現在、東京在住ではない(地方に飛ばされました(T_T)ので、買えません・・・。
0425デフォルトの名無しさんNGNG
誰か俺にIMonikerをやさしく解説してください。
このインタフェース訳わからんです。

どう実装していいのかどう使っていいのか
何のためにいるのか、さぱーりわかりません。

ちなみにInsideOLE読みました。でもわかりません。
0426デフォルトの名無しさんNGNG
IMonikerはIClintonを陥れたりするために使います。
0427デフォルトの名無しさんNGNG
IMoniker に I はない。あるのは、ただ欲だけ(:´Д`)
0428デフォルトの名無しさんNGNG
うまいなぁ。
0429デフォルトの名無しさんNGNG
COM+ってこれからどうなるの?
良く分からないは、レジストリから切り離されるって噂。
それと、64bitVBが出ないんなら、64bitCOM+が出ないって事?
0430デフォルトの名無しさんNGNG
MFCをかじった程度の初心者です。教えてください
・COMってなんですか?入門ページありますか?
・COMって今後はどうですか?
0431デフォルトの名無しさんNGNG
こちらからお入りください (W
COM プログラミングの基本
http://www.microsoft.com/japan/msdn/thisweek/combasics/combasics1.asp
0432デフォルトの名無しさんNGNG
タイプイライブラリを#importを使わずにC言語で
読み込む方法を教えて下さい。(VC6またはBCC)
0433斬ってくれ!NGNG
ITypeLib や ITypeInfo とか使えば?
そういうことじゃなくて?
0434ProxyNGNG
VBScript エンジンと JScript エンジンではアーキテクチャという観点から
どのようなメリット、デメリットがありますか?
たとえば文字列において VBScript では BSTR、 JScript ではオブジェクト、
実行速度などで差が出てくるものなのでしょうか?
0435432NGNG
>>433
>ITypeLib や ITypeInfo
多分それです。知りませんでした。
これもQueryInterfaceやGetIDsOfNamesで取ってこれるんでしょうか。
0436デフォルトの名無しさんNGNG
>>434
やってみれば?
0437デフォルトの名無しさんNGNG
QueryInterface(IID_ITypeInfo, &pTypeInfo)だろ。多分。
0438233NGNG
ITypeLib ITypeInfo
で検索しても日本のサイトはほとんど引っかかりませんね。
本の索引とかばっかりで。
タイプライブラリの参照で参考になりそうなWebサイトがありましたら
紹介してください。
0439432NGNG
s/233/432/
0440デフォルトの名無しさんNGNG
    ...
0441IUnknownNGNG
>432

私の場合、ほとんどの情報や技術は MSDN ライブラリと
専門書から学びました。まあ専門書は高いですし、簡単に
買えとは言えませんが、MSDN ライブラリはお持ちでないの?

持って無くても以下のサイトで見ることが出来ます。

msdn.microsoft.com/library/

ここで次のように階層を辿って下さい。

Component Development
  Automation
    SDK Documentation
      Automation
        Type Description Interfaes


あと厳しいようですが英語が読めないというのは論外です。
専門技術を身につけるには英語力は必須ですからね。
0442デフォルトの名無しさんNGNG
ひょっとして、ASPからはCOMを使ってもレジストリの中身は見れないんですか?
実行ユーザの権限が低いから
0443デフォルトの名無しさんNGNG
>>442
NT,W2K,XPだとレジストリにもセキュリティ属性というものがあるんよ。
0444デフォルトの名無しさんNGNG
>>443
やっぱりそうですか・・・
IISの匿名アクセスユーザをAdministratorとかに設定させるしかないのかな?
0445デフォルトの名無しさんNGNG
Usersで十分。Readがあればいいんでしょ。
0446デフォルトの名無しさんNGNG
>>445
とおもってUsersのユーザにしたけどだめでした。

そしてなぜかAdministratorsにしてもだめでした。
コンピュータの管理者(XPなので・・・)にしてみたらできました。

へんですね。コンピュータの管理者も所詮所属グループがAdministatorsになってる
だけなのに・・・
0447デフォルトの名無しさんNGNG
iisresetしてやりなおし。
0448デフォルトの名無しさんNGNG
>>447
ありゃ?できました。
IIS画面で停止->COM+のIIS????をシャットダウン->IIS画面で起動
までやったんで大丈夫かと思ってたのに。

iisresetってさらに何かやってんですね。どうやら。

・・・けどやっぱりUsersだけだとだめでした。たぶん自分の見に行ってるレジストリの
権限が高いんですね。きっと。
0449デフォルトの名無しさんNGNG
COMにしたDLLに、自分自身がインストールされているパスを返す関数を
組み込みたいのですが、うまい方法がわかりません。

Dllの仕組みの中にそういう機能ってありませんでしたっけ?
0450デフォルトの名無しさんNGNG
GetModuleFileNameをつかえばいいのでわ?
0451449NGNG
>>450
なにか期待と違う結果が・・・

C:\WINDOWS\System32\dllhost.exe

dllを呼び出した側のモジュール名が出てきました。?
0452デフォルトの名無しさんNGNG
>>451
DllMainで渡されるHINSTANCEを保存しておいて、それにGetModuleFileName()
0453449NGNG
>>452
ありゃ?だめだ。というかdllhost.exeってただしいっちゃ正しいんだけどね。
dllhost.exeってCOM+だけの話かとおもってました。
GetDllFileNameとかあればよかったんだけど。

HINSTANCE g_hInstance;
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
g_hInstance = hInstance;

}
--
extern HINSTANCE g_hInstance;
hoge()
{
TCHAR fileName[_MAX_PATH];
::GetModuleFileName(g_hInstance, fileName, sizeof(fileName));
}
0454449NGNG
失礼。できてました。(iisが前のをにぎりっぱなしでした)
0455デフォルトの名無しさんNGNG
昔ポプCOMっていう小学館からでてた雑誌あったなー
関係ないけど好きだった
0456デフォルトの名無しさんNGNG
VC++でreturn E_FAILをし、それをVBScript(ASP)で受けたいのですが、なぜか受け取れません。

エラー タイプ
(0x80004005)
エラーを特定できません

とは出るので、以下のように受けようとしても、Err.Numberは0のままなんです。

On Error Resume Next
MyCom.Hoge()
Response.Write("Error# " & Hex(Err.Number) & "<BR>")
Response.Write("Generated by: " & Err.Source & "<BR>")
Response.Write("Description: " & Err.Description & "<BR>")

On Errorじゃ受けられないんでしょうか?
0457デフォルトの名無しさんNGNG
>>456 自己レス
しまった。受ける場所を間違え・・・
しかし今度はE_FAILしかかえってこんな・・・
0458デフォルトの名無しさんNGNG
QueryInterface が失敗するのはどういう時ですか?

多分ちゃんと登録されているオブジェクトのはずなのですが、
確かめる方法からわかりません。
0459デフォルトの名無しさんNGNG
>>458
何かがマズイ時
0460デフォルトの名無しさんNGNG
そのインターフェースがインプリメントされていないとき。
0461デフォルトの名無しさんNGNG
>>456
ISupportErrorInfoとか調べてみてちょ
0462デフォルトの名無しさんNGNG
COMって.NETが普及すれば無くなるんじゃないの?
.NETからみたら過去の技術扱いでラッパーしかないですね。
0463デフォルトの名無しさんNGNG
どなたか!
IBindEventHandler インターフェースの
の、使い方(というか使われ方)を知ってる人いませんか?
解説書の書籍名でも結構です。情報をお待ちしております。
0464デフォルトの名無しさんNGNG
COMってVBのために作られたらしい
0465デフォルトの名無しさんNGNG
.NETランタイムが普及するまではCOMの天下
0466デフォルトの名無しさんNGNG
>>464
ならばVB.NETになった今は不要。
0467463NGNG
自己解決しました。
簡単にレポートすると、WSHなんかに公開するオートメーションオブジェクトで、
IBindEventHandlerを使えばIConnectionPointとかを使わずに動的に
イベントハンドラを指定させたりできるというものでした。

どっかにドキュメント用意しとけよ!>M$
0468デフォルトの名無しさんNGNG
COMを今から勉強しても無駄なんですか?
0469デフォルトの名無しさんNGNG
無駄の定義による。

windowsの既存のコンポーネントをガリガリ使うなら基礎知識として
知っておいたほうがいいかも。選択肢がいろいろ広がる。
まあこれからは.NETから使えるようになるだろうから、そこまでの
プライオリティがあるとは思えんがね。
0470デフォルトの名無しさんNGNG
>>464

COMが最初に登場したのはOLE2ではなかったか?
インプレースアクティベーションを実現したかったから。
そのためにOLE WindowやData Objectがでてきて
COMというアイデアがでてきたと俺は解釈していた。(DDEはもう限界だ)

この流れにVBの話は1つもなしで、
今VBで自由に扱えるディスパッチインタフェースは
後になっての話でVB3で初めて使えるようになった。

さらに後になってインプレースアクティベートが発展して
OLEコントロールというしくみに発展する。

間違っていたらすまん。
0471デフォルトの名無しさんNGNG
だれかプロパティとメソッドの違いを教えてくれ
0472デフォルトの名無しさんNGNG
違わない。プロパティはメソッド。
0473デフォルトの名無しさんNGNG
>>472
「プロパティ⇒メソッド」は成り立つが「メソッド⇒プロパティ」は成り立たんだろ。
まったく同じみたいな書き方するなって。
0474デフォルトの名無しさんNGNG
>>473
472は「プロパティはメソッド」と書いてあるだけで「メソッドはプロパティ」とは
書いてませんが。
0475デフォルトの名無しさんNGNG
ITypeInfo::GetFuncDesc(unsigned int index, FUNCDESC** ppFuncDesc)で
(*ppFuncDesc) ->invkindが、

INVOKE_PROPERTYGETかINVOKE_PROPERTYPUTかINVOKE_PROPERTYPUTREFなら
そのファンクションはプロパティ。

INVOKE_FUNCなら、そのファンクションはメソッド。

OK?
0476デフォルトの名無しさんNGNG
>違わない。
と書いてますが。
0477デフォルトの名無しさんNGNG
>>475
ITypeInfoって、どうやって取得するの?
0478475NGNG
>>477
IDispatch::GetTypeinfoあたりからどうぞ。

結局、プロパティとメソッドはともに(必ずしもとは言えないけどたいていは)
IDispatchからInvokeできる関数ディスクリプタ。
その関数ディスクリプタがPROPGETやPROPPUT, PROPPUTREFとマークされているものを
とりあえず、プロパティと呼ぶ。とりあえずというのはオブジェクトが
プロパティと主張しているだけでコントローラがプロパティとして扱うかは
別だから。でも扱わないケースを見たこと無いけどね。
関数ディスクリプタがFUNC(やMETHOD)とマークされていればそれはメソッドとして
扱ってくれということ。プロパティと同じでオブジェクトの心、コントローラ知らず。

あと異なる点は、同じ関数ディスクリプタを異なる種類(Invoke Kindというらしい)
で呼び出すことができるという点。同じ関数ディスクリプタに対してPUTとGETができる。
(PUTREFなんてのもあるけどおいておいて)

たいていはPUTしたものはそのままGETできるし、PUTによってオブジェクトの状態(色とか)が変わったりする。
場合によってはオブジェクト自身がプロパティを勝手に変更したりするが
この場合はIPropertyNotifyでコントローラに通知したりすることができる。(うる覚え)
必ずしもPUT, GET両方ともサポートする必要は無し。どっちか片方なんてのはザラ。
読み取り専用プロパティなんていうのは、GETのみね。

今日のところはこの辺でカンベン。
眠くてなに言っているのか自分でもよくわかんなくなった。
おやすみ、またあとで。
0479デフォルトの名無しさんNGNG
>>478
ありがとう。
0480IUnknownNGNG
結局 COM インターフェイスのメソッドとスクリプト言語等のメソッドを
同義に捉えてはいけないんだよね。それがいつも混乱の元になる。
472〜474のやり取りではそれが浮き彫りになってるね。

ひとつ気になったのはプロパティとメソッドの違いを問う人が、いきなり
475氏の説明を読んで理解できんのかな?って思う。「ありがとう」って
書いているし、要らぬお世話かな...。
0481477=479NGNG
>>480
>>ITypeInfoって、どうやって取得するの?
>IDispatch::GetTypeinfoあたりからどうぞ。
これに対しての「ありがとう」です。
後半はよくわかりませんでした。

わからないと言えば他にも。
各メソッド/プロパティで設定したり取得したVARIANT型の変数の
開放は誰が行うべきなのか?とか。
getで得たものは自分で開放すべきなのはなんとなくわかりますが・・
0482デフォルトの名無しさんNGNG
COMの基本がなってないねー。[in][out]によって誰が解放すべきかは決まっているのだよ。
0483デフォルトの名無しさんNGNG
あ〜、夕べ眠くて、自分でも何かいているのかわけわかんねぇ。

平たく言えば、オブジェクトがそれをプロパティと言えばプロパティ。
メソッドといえばメソッド。

プロパティは同じ関数をGET/PUTと違う種別で呼び出せる。
メソッドの呼び出す種別は一種類だけ。

ということです。眠くなくても何言っているのかわからんね。


>各メソッド/プロパティで設定したり取得したVARIANT型の変数の
>開放は誰が行うべきなのか?とか。
>getで得たものは自分で開放すべきなのはなんとなくわかりますが・・

質問の意図はおそらく、VARIANTそのものの開放ではなく
BSTR* VARIANT::pbstrValのようにポインタの先に値の実体が
あるようなVARTYPEで、そのポインタの先の領域はだれが開放するのか
ということだろう。getでもらうにしても、あらかじめ
VARIANT構造体を渡してそこに入れてもらうしかないし。

パラメータの受け渡しにかぎらず
VARIANTについては以下のような単純なルールを守っていれば問題ないかと。

1.VARIANT構造体の実体を宣言したら、それに対してVariantInit()すること。
 例:VARIANT var; VariantInit(&var);
2.VARIANTに値を入れる場合は、前もってVariantClear()しておくこと。
 VariantClearはVariantのvtにあわせて、中身の開放も行ってくれる。
 例:VariantClear(&var); var.vt = VT_I4; var.lVal = 2222;
 VariantCopy()を使う場合はコピー先にVariantClearが行われるので不要。
3.VARIANT構造体の実体を消す(あるいはauto変数で自動的に消えそうな)場合は
 前もってVariantClear()しておく。でないとリークする。


最終的に開放の責任を負っているのはそのVARIANT型の変数を割り当てた人。(ルール3)
VARIANT型の割り当てだよ、pbstrのようなVARIANTの中身の割り当てでは無いよ。
もらった側に最終的な開放の「義務」はない。
ただ、Byref渡しがあるので開放してはいけないということではない。(ルール2)
もらったVARIANTの中身を別の値、はては別のvtにする場合もあるので
その場合は中身を開放する必要があるんで。

渡す場合でも渡される場合でも、このルールに従えばいいと思う。

長くてすまん。間違っていたらすまん。だれかフォローしてくれ。
0484IUnknownNGNG
>プロパティは同じ関数をGET/PUTと違う種別で呼び出せる。
言いかえるならば「同じ関数名」ですね。get_、put_ が呼び出している
関数は異なる関数です。

VARIANTについては
「初期化する前のVARIANTにVariantClear()を行ってはならない」
VariantClear() は渡されたVARIANTを意味のあるものとして解釈するため、
初期化前のでたらめなデータが入っているVARIANTに対して使うと
無意味な参照を開放しようとしたり何が起こるかわからない!
(VARTYPEの解釈次第)

「クリアされていないVARIANTにVariantInit() を行ってはならない」
VariantInit() は渡されたVARIANTを意味の無いものとして解釈するため
BSTR やオブジェクト等のデータを保持しているVARIANTに対して使うと
これらは開放されること無くメモリに残り続けることになる。

って具合ですかね。当たり前のことですけど。
0485ななしーNGNG
メソッドやプロパティの戻り値で
他のオブジェクトのインターフェースを返すとき
どうやって宣言してますか?

自分としては、IFooとかを返したほうが良いような気がするのですが、
いろんなサンプルでは、ほとんどIDispatchとかVARIANTで返してるので、
なんでだろう?と思いました。
0486479NGNG
>>483-484
大変為になりました。
0487475NGNG
483で、名前欄書き忘れた475です。
>>484 フォローサンキューです。なのでフォロー返しです。

弁明すると、1つの関数 = 1つのDISPIDに対してという意味でして、、

get_, put_で関数が分かれているのはデュアルインタフェースで
組まれているインタフェースのケースですね。
(というか、今時IDispatchを実装するのにデュアルが普通でしょ?)
この場合はvtblの要素がget_, put_で二つに分かれているので
関数が二つ必要ということです。(当たり前のなりゆきですが)
名前が、プロパティhogeに対してget_hogeとput_hogeになるのは
midlがそういうヘッダファイルを生成するから。

>「初期化する前のVARIANTにVariantClear()を行ってはならない」
それ以前にVariantInit()されていないVARIANTはVARIANTで無い
ということでしょう。当然他のVariantXxxx()にも
VariantInitされていないVARIANTを渡してはいけない。


>>485
メソッドやプロパティという単語が出てきているから
IDispatch経由ということでいいでしょうか?
それなら、IFooのようなオリジナルインタフェースは
引数に指定できないから。

渡すにせよ、もらうにせよ
パラメータに指定できるインターフェースは
(VARIANTの中身を含めて)IDispatchかIUnknownしかない。
なので、IDispatchかIUnknownを受け取った側でQueryInterfaceして
本当にIFooかを確認すればいいかと。

ところでスレの趣旨からしてrawなCOMの場合の話でいいんだよね?
0488デフォルトの名無しさんNGNG
「rawなCOM」ってなんでしょうか?
unixでいうraw/cockedの関係?
0489デフォルトの名無しさんNGNG
いんや、補助ライブラリ使用しないって事では。
0490475NGNG
>「rawなCOM」ってなんでしょうか?

すんません。説明不足です。
IDispatchの話にはVB辺りを絡めて考えている人もいると思い、
「VBでのCOMではなく、>>1 に従って、生(raw)のCOMでいいんですよね?」
ということです。

0491デフォルトの名無しさんNGNG
IDispatchってVBのために作られたような気がせんでもないがなー
late binding以外にIDispatchの利点てありますか?
0492デフォルトの名無しさんNGNG
近頃はVBよりもJSやVBSの為ですかね。
IDispatchExとか言ってみるテスト。
0493475NGNG
私もCOM(というかOLE2)を勉強し始めたときに
「IDispatchってなんで必要なんだろう?」
と疑問におもっていた。で、俺流の解釈は

1. インタプリターだとこういうほうが扱いやすいのか
と自分を納得させていましたが、
いまや、VBでさえ、IDispatchなんて関係なく
カスタムインタフェースを呼べる、実装できる。
(oleautomationの制限はあるけど)

2.中間コードも作らない純粋なインタープリターだと
カスタムインタフェースを「呼び出す」のはなんとかできても
カスタムインタフェースを「実装」するには難しいと思う。
あらかじめ、全メソッドがわかっていないとvtblを作ることができないので。

その点、IDispatchは、メソッド名を問われた時点で考えれば
いいからやりやすい。

VBは開発環境で実行してもこっそりコンパイルしてコードを作って
動かしているような感じがするので、純粋ともいえないと思う。


3.「何にも考えなくてもマーシャリングできる」
(でもlongにポインタなんか入れたらダメだけど)
とも思いつつも、
カスタムインタフェースでも
ほぼ、自動的にマーシャラを用意できる。

結局、利点は2かな?
0494デフォルトの名無しさんNGNG
何を理由かこつけてんの?IDispatchはVBのためにVBチームが作った
インターフェイス。以上。VBがIUnknownを扱えるようになったのは
ずっと後の話。
0495IUnknownNGNG
>492
確かに。

VBScript の Class ステートメントの定義から作られる
オブジェクトなんかは内部的には IDispatchEx 経由で
アクセスするからね。正直このステートメントの実装を
可能にするために IDispatchEx は出来たんだろうね。
(いやまあ、推測だけど...。)
0496475NGNG
>>494 おそらく私宛だと解釈して

>何を理由かこつけてんの?
いや、理由をかこつけているのではなく
IDispatchを使う利点をかこつけているのですが。

>IDispatchはVBのためにVBチームが作ったインターフェイス。
そうですか。うすうすは感じていましたが。知りませんでした。

>VBがIUnknownを扱えるようになったのはずっと後の話。

「いまや、VBでさえ、IDispatchなんて関係なく
カスタムインタフェースを呼べる、実装できる。」
の「いまや」でその辺を示していたんですが。
あまりハッキリして言っていませんでしたね。すみません。

私の記憶では、VBでのCOMサポートはVersion3で
IDispatchドライバになることができた。
Version4でIDispatchオブジェクトになれて
Version5で制限ながらIUnknownオブジェクトになれる。

でしたっけ? 実はVB3って使ったことないんですが
OLE2 SDKについていたDISPTESTとかいう
テスト用のオートメーションドライバが
VB3のサブセットということを聞いたことがあるので。
0497デフォルトの名無しさんNGNG
VCスレに逝くべきかもしれませんが、COM特有なのでここで質問。

#define _WIN32_WINNT 0x0400
#define WINVER 0x400
#include <windows.h>
#include <tchar.h>
#include <comdef.h>
#include <objbase.h>

#undef DialogBoxW
#pragma comment ( lib, "Rpcrt4.lib" )

#import "xl5jp32.olb" \
rename("DialogBox", "DialogBoxForExcel") \
rename( "RGB", "RGBForExcel")


int foo()
{
CoInitializeEx(0, COINIT_MULTITHREADED);
Excel::_Application *pRawExcel = NULL;

VC6で上のコードをビルドすると、Excel::_Application の行で
C:\proj\src\libexcel\libexcel.cpp(18) : error C2039: '_Application' : 'Excel' のメンバではありません。
C:\proj\src\libexcel\libexcel.cpp(18) : error C2065: '_Application' : 定義されていない識別子です。
なかんじのエラーが出てしまいますが、何がまずいんでしょうか?

C++からexcelのセルがいじれてマクロが呼べればどのようなやり方でもいいんですけど、
そのへんから拾ってきたコードも、MSDNのサンプルもろくにビルドできずに困ってます。
0498デフォルトの名無しさんNGNG
ちなみに、excel9.olbをインポートすると、かわりに
c:\proj\src\libexcel\debug\excel9.tlh(1194) : error C2504: '_IMsoDispObj' : 定義されていない基本クラスが宣言されています。
みたいなエラーがたくさん出てきます。

はひゅー
0499デフォルトの名無しさんNGNG
>>497
CoInitializeEx(0, COINIT_MULTITHREADED);
Excel::_ApplicationPtr pRawExcel( __uuidof( Excel::Application ) );

これでいかないか?
タイプライブラリをインポートすると、生のインターフェイスの代わりに
スマートポインタ版インターフェイスが定義されるはず。
_com_ptr_t<>ってやつ。インターフェイス名にPtrと付く事に注意。
スマートポインタなんで普通NULLは入れないな。
0500デフォルトの名無しさんNGNG
純粋にC++だけやってるからか
オートメーションやアクテブXの存在理由がイマイチわからん。
使うこともないし。何の意味があるのこれ?
C++を使う上で、無意味ともとれる決まりごとが多くてかなわん。
VBとかで使う為に必要なんですよとかそんなの理由になるのか?
.NETの本にCOMが難しいのは、本来OSが受け持つサービスを
自前で用意しなければならないからだとか書いてあったが正しくその通り。
0501デフォルトの名無しさんNGNG
>>500
> VBとかで使う為に必要なんですよ

.NETもそういう決まりごとでがんじがらめになってるけど、
コードを書く側にとって見えなくなってる。それがCOMとの違い。
COMは負担が大きすぎた。
0502497NGNG
>>499
ありがとーん
あの後、MS09.olbとかVB6EXT.olbとかいること発見したんで、EXCEL9.olbを
使うように戻しました。

#import "C:\Program Files\Microsoft Office\Office\MSO9.DLL" \
rename("DocumentProperties", "DocumentPropertiesXL")
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\Office\EXCEL9.OLB" \
rename("DialogBox", "DialogBoxXL") \
rename("RGB", "RBGXL") \
rename("DocumentProperties", \
"DocumentPropertiesXL") \
no_dual_interfaces \
exclude("IFont","IPicture")

int foo()
{
CoInitializeEx(0, COINIT_MULTITHREADED);
Excel::_ApplicationPtr pRawExcel( __uuidof( Excel::Application ) );
pRawExcel->Quit();

return 0;
}

でもやぱーり、
c:\proj\src\libexcel\debug\excel9.tli(3731) : error C2511: 'PutOnDoubleClick' : オーバーロードされたメンバ関数が '<Unknown>' にありません。
なんてのが出てきてお手上げ状態です。

web上にも完全なコードやOLB間の依存関係の情報があまりないところを見ると、
#importではみんなうまくいかなくてあきらめちゃってるんじゃないかと思う次第であります。
0503499NGNG
>>502
折れも試しに作ってみたが、一応コンパイルは通ったよ。
動くかどうかは試してないけど。
普通にATL COM AppWizard でexeサーバー作ってる。

// Test.cpp : CTest のインプリメンテーション
#include "stdafx.h"
#include "EXCEL9_TEST.h"
#include "Test.h"

#import "E:\Program Files\Microsoft Office\Office\MSO9.DLL"
#import "E:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "E:\Program Files\Microsoft Office\Office\EXCEL9.OLB" rename("DialogBox", "DialogBoxXL") rename("RGB", "RBGXL")

/////////////////////////////////////////////////////////////////////////////
// CTest
STDMETHODIMP CTest::a()
{
CoInitializeEx(0, COINIT_MULTITHREADED);

Excel::_ApplicationPtr pRawExcel( __uuidof( Excel::Application ) );
pRawExcel->Quit();

::CoUninitialize();

return S_OK;
}
0504497NGNG
>>503
ウワーン
#includeを付けたりはずしたらりしてたらビルドできるようになったよー

手順はこうです

>>497をふつうのWin32 Console exeで作成
↓
いろいろいじるがパーイ
↓
2chに泣きつく
↓
>>503を読んで、ATL COM AppWizardでexeサーバを作ってコンパイル
↓
Σ(゚д゚lll)ガーン動くよ
↓
#includeしてるヘッダが関係してるかと思って>>497に#include <atlcom.h>とか
#define STRICTとかいれてみる
↓
Σ(゚д゚lll)ガーンコンパイル通るよ
↓
元の>>497に戻してビルド
↓
Σ(゚д゚lll)ガーンコンパイル通るよ

という次第です。
コンパイラが作成する tlhとかが壊れてたのかなーと思ってみたりして。
0505497NGNG
というわけで野望に向けてようやく一歩前進です。

ところで、excel 97/98/2000/2002を同じようにC++側から操作したい場合、
ソースは一個で何とかなるんでしょうか?

それぞれのofficeのバージョンごとにolbとか取り込まなきゃいかんのでしょうか?
0506499NGNG
>>505
折れはアマゲープログラマなんで
EXCELのことは全然わからんのですよ。( ´Д⊂
ただやっぱ、COMなんだから
EXCEL97〜EXCEL2002が
同じCLSIDを持つコーポネントを利用しているのなら
最新のOLD1つを対象に組むだけで良いんのではないかな?
0507497NGNG
互換性に関しては
__uuidof( Excel::Application )
のところがポイントですかね。
Excel97で持っているUUIDを渡すべきかな?

場つなぎ的なサンプルしかないのでこれも試行錯誤するしかないですね。
0508デフォルトの名無しさんNGNG
バージョンなしのProgIDを使えばいい。
が、97〜2002で全く挙動が一緒だという保証はないと思うが。
0509497NGNG
"Excel.Application.9" みたいなのがバージョン付きで
"Excel.Application" みたいなのがバージョンなしのProgIDなんでしょうか。

やりたいことはセルの値の取得と設定、マクロの起動くらいなので
バージョンには依存しないと思われます。

最新のOLD+バージョン無しProgIDの線で攻めてみます。
0510499NGNG
>>507
調べまくってわかりました。
EXCEL95がxl5jp32.olb、
EXCEL97がEXCEL8.olb、
ELECEL2000がEXCEL9.olbなんですね。
それで折れが調べた限り
xl5jp32.olbとEXCEL9.olbは
コーポネント上の互換性は無いみたいです。
インターフェイスやそのメソッドとかは
なんとなく似てるんですが。
自分のWin2000ではxl5jp32.olbのインターフェイスを呼ぶと
何故か失敗するので確かめることはできなかったんですけど。
EXCEL8.olbは手元に無いのでわかりませんでした。
0511497NGNG
こりゃああきらめてVBを間に挟むしかないかな。
0512デフォルトの名無しさんNGNG
↑みたいなのを#importを介さずに同じ事するにはどうすんだべ?
BCCからも使いたいっぺ。
■ このスレッドは過去ログ倉庫に格納されています