COM の世界を斬る!
■ このスレッドは過去ログ倉庫に格納されています
0001IUnknown
NGNG0382デフォルトの名無しさん
NGNGATLのIConnectionPointの実装だと(純粋なCOMというスレの趣旨だがサンプルということで)
Adviseしたオブジェクトのシンクインタフェースへのポインタを固定長の配列で保持している。
だからUnadviseし忘れたオブジェクトがいくつもあってもそのうち、保持しきれなくなる。
あとからAdviseしてきてもCONNECT_E_CANNOTCONNECTと返すほか無くなる。
人によってはIConnectionPointの実装を可変長配列やリストで管理していたりする。
そうなるとおそらくヒープにとるので、Unadviseされないとメモリリークになる。
よくありがちなのが、クライアントが死んでものだからしょうがなく再起動するを繰り返したりする場面。
クライアントが異常終了から再起動するたびに、どんどんメモリリークするかAdvise可能な回数が減る。
DCOMをつかってサーバーから接続しているクライアントに一斉にイベントを投げるようなシステムは気をつけたほうがいい。
こんな状況でもAdviseを受け付けられるようにメモリリーク覚悟でヒープからとるか
固定長の配列で、あふれるようなら拒否するかどっちが良いか悪いかわからんが問題があることは確かだ。
(俺としてはAdvise可能な回数は制限したほうがいいと思うけど)
というわけでイベント送出時にRPC_E_なんとかとなったら自分でUnadviseするのが無難だろ。
VBは自分でUnadviseなんかできないな。
VB屋さんが、DCOMで簡単にサーバークライアントシステムが組めるや、
ちょちょいのちょい。なんて調子で安易にDCOMを使って、
しまいにはどうしたらいいかわからなくなる。
これでもWindowsDNA(死語)の基幹テクノロジーなんだがね。
0383デフォルトの名無しさん
NGNG0384デフォルトの名無しさん
NGNG0385デフォルトの名無しさん
NGNGおいおい、リモート・ローカル等価性はどうなったんだ?
IConnectionPointはリモートで使ってはいけないから
リモートとローカルで等価ではないってことだな。
実はリモートに限らずローカルサーバーもやばいんじゃないか?ということで等価か。
とIConnectionPointひとつを重箱の隅を突くように取り上げて煽ってもしょうがないが
現実問題として、IConnectionPointに限らず、リモートオブジェクトから
インタフェースを渡されるような場面は気をつけたほうがいい。
渡してきた相手がこそっり死んでいるようなこともあるんで。
0386デフォルトの名無しさん
NGNGVBはUnadviseを勝手にやってくれたりはしないのかな?
0387デフォルトの名無しさん
NGNGそうではない。ここで問題になっている程度の、それなりにそれなりが要求される環境で、
しかもDCOMを使っている場合ってこと。
>>385
Effective COM読んでね。
9. Avoid connection points
0388デフォルトの名無しさん
NGNG0389デフォルトの名無しさん
NGNGVCでCOMつくってVBScriptから使おうと思ったんですが、
VBScriptに2つ以上の返り値を戻す方法がわかりません。
つまるところ、
Set Hoge = CreateObject("Hoge.Hoge")
Status = Hoge.Func(InVal, OutVal, OutVal2)
IF OutVal = "aaa" And OutVal2 = "bbb" Then
みたいな設計はできないんでしょうか?
0390デフォルトの名無しさん
NGNGできません。VBScriptの制限事項です。
0391389
NGNGがっくし。SAFEARRAYとVARRANTつかって配列で受け渡しするしかないか・・・
0392デフォルトの名無しさん
NGNGCOM側(VC):
[propget, id(10), helpstring("プロパティ RemoteHost")] HRESULT RemoteHost([out, retval] BSTR *pVal);
[propput, id(10), helpstring("プロパティ RemoteHost")] HRESULT RemoteHost([in] BSTR newVal);
クライアント側(VBscript):
Hoge.RemoteHost = "myhost"
みたいな。
でこの場合、getやputでエラーとなった場合の処理ってどう実装すればいいんでしょうか?
とくにputの場合エラーとなってもクライアントは判定できないです。
0393デフォルトの名無しさん
NGNG0394デフォルトの名無しさん
NGNG0395393
NGNGVBSならON ERRORで処理するんちゃうんか?
それともVBSはput時のエラーは無視する仕様なの?
0396ななし
NGNGVBからオートメーションでExcelを操作するのに、事前バインドと実行時バインドでどのくらい
レスポンス差があるのか気になって、
(1) 事前バインドで Dim .... As New Excel.Application
(2) 事前バインドで Dim .... As Excel.Application → Set .... = New ... でインスタンシング
(3) 事前バインドで Dim .... As Excel.Application → Set .... = CreateObject ... でインスタンシング
(4) Dim .... As Object → Set .... = CreateObject ... で実行時バインド
の4通りを比較してみたところ、(4)が一番速いという、予想外(常識はずれ)の結果となってしまい
ました。(ベンチマークの内容は、DAOのRecordsetをExcelに出力する、というもの)
COMの解説書には、事前バインドの方が高速と書いてありますが、どうして期待した結果にならないの
でしょうか?
ちなみに、インプロセスサーバを参照してコンパイルしたEXEを該当するコンポーネントがレジスト
されていない端末で起動するとプロセスが起動せずにクラッシュしますが、上記(1)〜(3)のEXEを
Excelがインストールされていない端末で起動しても、エラーにならずに正常に起動してしまいます。(無論、オートメーション機能は動きませんが)
インプロセスコンポーネントと、アウトプロセスコンポーネントでは、バインドの仕組みが違うの
でしょうか?
ご存知の方、コメントお願いします。m(_ _)m
0397ななし
NGNG環境は、VB6.0 SP5 + Excel8.0 SR-2 です。
Windows 98 / NT4.0 ws SP6
のどちらでも、
> (4) Dim .... As Object → Set .... = CreateObject ... で実行時バインド
が最速でした。
0398デフォルトの名無しさん
NGNG0399ななし
NGNG>>398
ソースが現在手元に残ってないのでアレですが、50000件のレコード(DAO.Recordset)を
セルに出力する時間を計測しました。
インスタンス化 → Nothing までの時間です。
無論、現実的には、二次元配列を使うなり、CopyFromRecordsetメソッドを使えば一発の
処理なのですが、メソッドやプロパティの参照回数を増やさないと明確な差が検出でき
ない?と考えたので、1件ずつループしてます。
0400デフォルトの名無しさん
NGNGケース毎にプログラム終了した?
exeにコンパイルして試した?
ケース毎にマシン再起動した?
0401デフォルトの名無しさん
NGNG(総時間) = (一件当たりの時間) * (件数) + (定数)
になるから
件数を変化させたときの時間の変化を見れば、
もう少し分かったと思うんだがなあ・・・
ソースコードがないんじゃあもう無理か。
ちなみにそれぞれの時間を覚えてない?
0402ななし
NGNG当然、IDEではなく、EXEでテストしてますし、プログラムも1回毎に立ち上げ
直しました。マシンのリブートまではしてませんが。(やるべきでした?)
それと、レスポンスの計測にTimer関数を使用したので、測定誤差はあるかも
しれません。でも、誤差が出るのは、(1)〜(4)までおなじ条件なので、(4)に
だけ有利に働くなんてことはないですよね?
0403ななし
NGNGソースがないのは、今、実家に帰ってるから(^-^;で、自分とこのマシンにはちゃんと
あります。(件数をもう少し増やせば、というのはちらっと思いました)
ちなみに、このベンチマークをやったのは、昨年の9月頃です。
実行時バインドの方が高速だなんて、気でも違ったかと思われそうで、技術系のMLやBBS
に上げるのを躊躇してました・・・。
0404デフォルトの名無しさん
NGNG>ちなみに、インプロセスサーバを参照してコンパイルしたEXEを該当するコンポーネントがレジスト
>されていない端末で起動するとプロセスが起動せずにクラッシュしますが、上記(1)〜(3)のEXEを
CreateObjectでコケてるんですな。
>Excelがインストールされていない端末で起動しても、エラーにならずに正常に起動してしまいます。(無論、オートメーション機能は動きませんが)
こっちは、めそっど、ぷろぱてぃの情報がコンパイル時に解決されますね。
0405デフォルトの名無しさん
NGNG厳密に言うなら、ディスクキャッシュなどの影響をなくすために、
同じテストを3回以上繰り返すべき。(1なら1を3回実行する)
これで生の処理時間に近づけるはず。
あと、プロパティやメソッドの実行レスポンスを調べたいのであれば、
計測開始時刻と計測終了時刻 を ループ開始直前とループ終了直後 に
置いたほうがいいね。
4にだけ有利に働く可能性としては
a:単に最後に実行して、全部のデータがディスクキャッシュに乗っていた
b:4のみ >>401 のいう定数部分が小さい(あるいは1〜3は定数部分が大きい)
などがあると思う。
ベンチマーク(理科でいうところの対照実験)の基本なので、
このへんを押えてないと厨房扱いされちゃうよ。
0406デフォルトの名無しさん
NGNGエクセルを操作するのでアウトプロセスでしかもDispatchインターフェイスのみ
でしょう。
どの方法でも測定誤差程度しか違わないのではないでしょうか。
0407ななし
NGNGありがとうございます。
> b:4のみ >>401 のいう定数部分が小さい(あるいは1〜3は定数部分が大きい)
> などがあると思う。
その可能性はありそうですが、Excelの場合、行数に65536という制限があるので、
ベンチマーク方法をもう少し工夫した方がいいのかもしれません。
私的に気になっているのは、メモリ上の操作ではなく、ファイル出力の
レスポンステストなので、複数回実行すると環境が汚れることによる影響
があるんじゃないかと・・・?
0408ななし
NGNGありがとうございます。
> エクセルを操作するのでアウトプロセスでしかもDispatchインターフェイスのみ
> でしょう。
インプロセスとアウトプロセスではバインド方法が違う、という理解でよろしいの
でしょうか?
使っている言語がVBオンリーな上、COMのメカニズムもあまり理解していないので、
このスレの話題についてくのはしんどいです・・・。(T_T)
0409デフォルトの名無しさん
NGNG0410409
NGNG対象のプロセスとインターフェースの型と、インターフェースへのポインタだけです。
CoCreateInstance()などで取得できるものではありません。
0411409
NGNG0412デフォルトの名無しさん
NGNG0413デフォルトの名無しさん
NGNGお勉強レベルのスレがあってもいいかもね
0415409
NGNGただ、スタックトレースを見ると、たとえばドラッグ&ドロップなんかは
rpcrt4.dllなどを介してcallされているし、何か抜け道なりがあるのかもしれないと思って聞きました。
ちなみに、フックをかけてcallをする方法は試してみたところ成功しました。
0416デフォルトの名無しさん
NGNGだから、マーシャリング、プロキシ/スタブ、スレッドモデルなんかに
ついてもっと勉強しろや。
他のプロセスにあるinProc COMサーバを(その、「ほかの
プロセス」を実行主体として)呼ぶのは、フックでもしないと無理。
そうでないなら、普通にCreateProcessから呼び出せば、
あとはole関連ライブラリが善処してくれる。
0417406
NGNGバインド方法とサーバのプロセス形態は直接は関係ないですよ。
バインド方法はVBのソースで型名でオブジェクトを扱うのか、
Objectで扱うのかの違いでしょ。
一般的にVBでいうところのバインドは、
参照を追加して型名で操作 == アーリーバインド
開発時に型情報等を解析する
サーバへのバージョン依存性は高くなるが
開発時にエラーチェックできる
またパフォーマンスはよい
object型で操作 == レイトバインド
実行時に型情報等を解析する
サーバへのバージョン依存性は低くなるが
実行時エラーになる可能性もある
またパフォーマンスはさがる
という事で >>396 でなぜレイトバインドが一番速かったのか
と疑問に思っているのではないでしょうか。
#ちなみにnewとCreateObjectはオブジェクトを作るときのみ
#違いがあるので受けた後の型しだいで上記と同じ。
バインド方法で著しくパフォーマンスがかわるのは
dualインターフェイスのインプロセスサーバを扱った
ときでしょう。アーリーバインドで開発時にIUnknown側の
メンバーを扱う様にコードが吐かれるのか、レイトバインド
で実行時にDispatchのInvoke経由でメンバーを扱うのかという。
たとえdualインターフェイスでもアパートメントに互換性が
あるインプロセスサーバ以外は直接サーバとは対話していない
ので注意が必要です。
しかし >>396 で検証した結果レイトバインドが速いというので
あれば、仮説ですがVBがDispatchのみのエクセルに対して
アーリーバインドするとエクセルを扱う仮想のエクセルオブジェクト
を作成しているとか、使用しないメンバー情報等も全て
取得してまうとか...そのぐらいでしょか。
結局エクセルを扱うときDispatchでInvokeするしかないわけだから
アーリーバインドする事でどのぐらいパフォーマンスに差がある
かといわれると「誤差ぐらい」と思われますが。
0418ななし
NGNG丁寧なコメント、ありがとうございます。m(_ _)m
残念ながら、私は勉強不足のようです。(VBユーザーは、COMを「使う」ことはあっても、
内部の仕組みは必ずしもしらなくても足りてしまう場合が多いので)
このスレの話題について行けるよう、いろいろ研究してみます。
ソフトウェアの動作原理や(隠蔽された)内部のふるまいに興味が大いにありますので。
0419D
NGNG0420デフォルトの名無しさん
NGNGたしか前者は入手困難じゃなかった?
0421D
NGNG速攻買いに行きました。ここまで高い本買ったのは初めてだったが
かなり勉強になるよ。入手出来なければ大きめの図書館で借りたりとかね。
家の近郊の図書館にはInside OLEはあった。まあ購入後知ったことだから
どうでもいいんだけどね。常に手元に無いと落ち着かないって言うのもあるし
損した気分にはならなかったね。今の学生さんならお金持ってるだろうし
そんなに負担ではないのでは?(いいかげんな推測ですが)
0422ななし
NGNGいちおう、ええ歳こいた社会人(0x20代)なので(にしては、厨房質問ですが(^-^;;;)、
本くらいは買えます。
「Inside COM+」ですね。
ありがとうございました。m(_ _)m
0423デフォルトの名無しさん
NGNG俺が立ち読みしてるので、絶対に買うな。お長居します。
0424ななし
NGNG現在、東京在住ではない(地方に飛ばされました(T_T)ので、買えません・・・。
0425デフォルトの名無しさん
NGNGこのインタフェース訳わからんです。
どう実装していいのかどう使っていいのか
何のためにいるのか、さぱーりわかりません。
ちなみにInsideOLE読みました。でもわかりません。
0426デフォルトの名無しさん
NGNG0427デフォルトの名無しさん
NGNG0428デフォルトの名無しさん
NGNG0429デフォルトの名無しさん
NGNG良く分からないは、レジストリから切り離されるって噂。
それと、64bitVBが出ないんなら、64bitCOM+が出ないって事?
0430デフォルトの名無しさん
NGNG・COMってなんですか?入門ページありますか?
・COMって今後はどうですか?
0431デフォルトの名無しさん
NGNGCOM プログラミングの基本
http://www.microsoft.com/japan/msdn/thisweek/combasics/combasics1.asp
0432デフォルトの名無しさん
NGNG読み込む方法を教えて下さい。(VC6またはBCC)
0433斬ってくれ!
NGNGそういうことじゃなくて?
0434Proxy
NGNGどのようなメリット、デメリットがありますか?
たとえば文字列において VBScript では BSTR、 JScript ではオブジェクト、
実行速度などで差が出てくるものなのでしょうか?
0435432
NGNG>ITypeLib や ITypeInfo
多分それです。知りませんでした。
これもQueryInterfaceやGetIDsOfNamesで取ってこれるんでしょうか。
0436デフォルトの名無しさん
NGNGやってみれば?
0437デフォルトの名無しさん
NGNG0438233
NGNGで検索しても日本のサイトはほとんど引っかかりませんね。
本の索引とかばっかりで。
タイプライブラリの参照で参考になりそうなWebサイトがありましたら
紹介してください。
0439432
NGNG0440デフォルトの名無しさん
NGNG0441IUnknown
NGNG私の場合、ほとんどの情報や技術は MSDN ライブラリと
専門書から学びました。まあ専門書は高いですし、簡単に
買えとは言えませんが、MSDN ライブラリはお持ちでないの?
持って無くても以下のサイトで見ることが出来ます。
msdn.microsoft.com/library/
ここで次のように階層を辿って下さい。
Component Development
Automation
SDK Documentation
Automation
Type Description Interfaes
あと厳しいようですが英語が読めないというのは論外です。
専門技術を身につけるには英語力は必須ですからね。
0442デフォルトの名無しさん
NGNG実行ユーザの権限が低いから
0443デフォルトの名無しさん
NGNGNT,W2K,XPだとレジストリにもセキュリティ属性というものがあるんよ。
0444デフォルトの名無しさん
NGNGやっぱりそうですか・・・
IISの匿名アクセスユーザをAdministratorとかに設定させるしかないのかな?
0445デフォルトの名無しさん
NGNG0446デフォルトの名無しさん
NGNGとおもってUsersのユーザにしたけどだめでした。
そしてなぜかAdministratorsにしてもだめでした。
コンピュータの管理者(XPなので・・・)にしてみたらできました。
へんですね。コンピュータの管理者も所詮所属グループがAdministatorsになってる
だけなのに・・・
0447デフォルトの名無しさん
NGNG0448デフォルトの名無しさん
NGNGありゃ?できました。
IIS画面で停止->COM+のIIS????をシャットダウン->IIS画面で起動
までやったんで大丈夫かと思ってたのに。
iisresetってさらに何かやってんですね。どうやら。
・・・けどやっぱりUsersだけだとだめでした。たぶん自分の見に行ってるレジストリの
権限が高いんですね。きっと。
0449デフォルトの名無しさん
NGNG組み込みたいのですが、うまい方法がわかりません。
Dllの仕組みの中にそういう機能ってありませんでしたっけ?
0450デフォルトの名無しさん
NGNG0451449
NGNGなにか期待と違う結果が・・・
C:\WINDOWS\System32\dllhost.exe
dllを呼び出した側のモジュール名が出てきました。?
0452デフォルトの名無しさん
NGNGDllMainで渡されるHINSTANCEを保存しておいて、それにGetModuleFileName()
0453449
NGNGありゃ?だめだ。というか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));
}
0454449
NGNG0455デフォルトの名無しさん
NGNG関係ないけど好きだった
0456デフォルトの名無しさん
NGNGエラー タイプ
(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しまった。受ける場所を間違え・・・
しかし今度はE_FAILしかかえってこんな・・・
0458デフォルトの名無しさん
NGNG多分ちゃんと登録されているオブジェクトのはずなのですが、
確かめる方法からわかりません。
0459デフォルトの名無しさん
NGNG何かがマズイ時
0460デフォルトの名無しさん
NGNG0461デフォルトの名無しさん
NGNGISupportErrorInfoとか調べてみてちょ
0462デフォルトの名無しさん
NGNG.NETからみたら過去の技術扱いでラッパーしかないですね。
0463デフォルトの名無しさん
NGNGIBindEventHandler インターフェースの
の、使い方(というか使われ方)を知ってる人いませんか?
解説書の書籍名でも結構です。情報をお待ちしております。
0464デフォルトの名無しさん
NGNG0465デフォルトの名無しさん
NGNG0466デフォルトの名無しさん
NGNGならばVB.NETになった今は不要。
0467463
NGNG簡単にレポートすると、WSHなんかに公開するオートメーションオブジェクトで、
IBindEventHandlerを使えばIConnectionPointとかを使わずに動的に
イベントハンドラを指定させたりできるというものでした。
どっかにドキュメント用意しとけよ!>M$
0468デフォルトの名無しさん
NGNG0469デフォルトの名無しさん
NGNGwindowsの既存のコンポーネントをガリガリ使うなら基礎知識として
知っておいたほうがいいかも。選択肢がいろいろ広がる。
まあこれからは.NETから使えるようになるだろうから、そこまでの
プライオリティがあるとは思えんがね。
0470デフォルトの名無しさん
NGNGCOMが最初に登場したのはOLE2ではなかったか?
インプレースアクティベーションを実現したかったから。
そのためにOLE WindowやData Objectがでてきて
COMというアイデアがでてきたと俺は解釈していた。(DDEはもう限界だ)
この流れにVBの話は1つもなしで、
今VBで自由に扱えるディスパッチインタフェースは
後になっての話でVB3で初めて使えるようになった。
さらに後になってインプレースアクティベートが発展して
OLEコントロールというしくみに発展する。
間違っていたらすまん。
0471デフォルトの名無しさん
NGNG0472デフォルトの名無しさん
NGNG0473デフォルトの名無しさん
NGNG「プロパティ⇒メソッド」は成り立つが「メソッド⇒プロパティ」は成り立たんだろ。
まったく同じみたいな書き方するなって。
0474デフォルトの名無しさん
NGNG472は「プロパティはメソッド」と書いてあるだけで「メソッドはプロパティ」とは
書いてませんが。
0475デフォルトの名無しさん
NGNG(*ppFuncDesc) ->invkindが、
INVOKE_PROPERTYGETかINVOKE_PROPERTYPUTかINVOKE_PROPERTYPUTREFなら
そのファンクションはプロパティ。
INVOKE_FUNCなら、そのファンクションはメソッド。
OK?
0476デフォルトの名無しさん
NGNGと書いてますが。
0477デフォルトの名無しさん
NGNGITypeInfoって、どうやって取得するの?
0478475
NGNGIDispatch::GetTypeinfoあたりからどうぞ。
結局、プロパティとメソッドはともに(必ずしもとは言えないけどたいていは)
IDispatchからInvokeできる関数ディスクリプタ。
その関数ディスクリプタがPROPGETやPROPPUT, PROPPUTREFとマークされているものを
とりあえず、プロパティと呼ぶ。とりあえずというのはオブジェクトが
プロパティと主張しているだけでコントローラがプロパティとして扱うかは
別だから。でも扱わないケースを見たこと無いけどね。
関数ディスクリプタがFUNC(やMETHOD)とマークされていればそれはメソッドとして
扱ってくれということ。プロパティと同じでオブジェクトの心、コントローラ知らず。
あと異なる点は、同じ関数ディスクリプタを異なる種類(Invoke Kindというらしい)
で呼び出すことができるという点。同じ関数ディスクリプタに対してPUTとGETができる。
(PUTREFなんてのもあるけどおいておいて)
たいていはPUTしたものはそのままGETできるし、PUTによってオブジェクトの状態(色とか)が変わったりする。
場合によってはオブジェクト自身がプロパティを勝手に変更したりするが
この場合はIPropertyNotifyでコントローラに通知したりすることができる。(うる覚え)
必ずしもPUT, GET両方ともサポートする必要は無し。どっちか片方なんてのはザラ。
読み取り専用プロパティなんていうのは、GETのみね。
今日のところはこの辺でカンベン。
眠くてなに言っているのか自分でもよくわかんなくなった。
おやすみ、またあとで。
0479デフォルトの名無しさん
NGNGありがとう。
0480IUnknown
NGNG同義に捉えてはいけないんだよね。それがいつも混乱の元になる。
472〜474のやり取りではそれが浮き彫りになってるね。
ひとつ気になったのはプロパティとメソッドの違いを問う人が、いきなり
475氏の説明を読んで理解できんのかな?って思う。「ありがとう」って
書いているし、要らぬお世話かな...。
0481477=479
NGNG>>ITypeInfoって、どうやって取得するの?
>IDispatch::GetTypeinfoあたりからどうぞ。
これに対しての「ありがとう」です。
後半はよくわかりませんでした。
わからないと言えば他にも。
各メソッド/プロパティで設定したり取得したVARIANT型の変数の
開放は誰が行うべきなのか?とか。
getで得たものは自分で開放すべきなのはなんとなくわかりますが・・
0482デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています