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

COM の世界を斬る!

■ このスレッドは過去ログ倉庫に格納されています
0001IUnknownNGNG
ATL や MFC でラッピングされていない素顔の COM について語り合いましょう。
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からも使いたいっぺ。
0513デフォルトの名無しさんNGNG
>>512
当然だが、C++からは直でタイプライブラリは読めないので
C++のソースファイルへの変換が必要。
#importディレクティブは、OLBファイルから
TLHとTHIというC++のヘッダとソースを作り出す。
それに加え、OLBファイルからツールを使ってIDLファイルを作成し、
IDLファイルからMIDLコンパイラを使ってC++ヘッダをコンパイルする方法もある。
上記二つのどっちかのC++ソースを、何らかの方法でゲットしてBCCで使えるかどうか
試す。
又は、COMの機能を使って動的にタイプライブラリを読み出す事も可能。
LoadTypeLibEx()でITypeLibインターフェイスを取得する方法。
0514デフォルトの名無しさんNGNG
一番古いバージョンのExcelのタイプライブラリをインポートして、
CLSIDFromProgID( "Excel.Application" )ではだめでしょうか?

だめなら、全てIDispatch経由でアクセスするしかないでしょうか...
0515499NGNG
>>514
497?
ならすいません。ウソこいてました。
EXCEL9.olbはxl5jp32.olbの上位互換性を持ってるようです。
xl5jp32.olbで公開されているインターフェイスは
dispinterfaceだけしかありません。
EXCEL9.olbはそれに加えdual interfaceとinterfaceを公開しているようです。
しかし、xl5jp32.olbで公開されている
dispinterface _Globalとdispinterface Applicationの
このふたつは何故かEXCEL9.olbには無いです。それ以外の
dispinterfaceは定義されているようです。
自分はEXCELにはあまり詳しくないんで
わからないんですが無くてもいいんですかね?
まあ結論としては、インポートするOLDはEXCEL9.olbで1つでOK。
ただし、xl5jp32.olbへのアクセスはIDispatch経由以外ないと、
こうなると思います。
0516499NGNG
>ただし、xl5jp32.olbへのアクセスはIDispatch経由以外ないと、
>こうなると思います。
xl5jp32.olbと互換性を持たせるなら、IDispatch経由以外ないと
の間違いです。
0517514NGNG
>>515 497ではないですが(^^;)

古いexcel等は確かおっしゃるとおりdispinterfaceしか定義されていなかった
と記憶しています。

そこで >>497 さんは #import を使っているみたいですから、#import すれば
Dispatch経由でアクセスしてくれるラッパが自動的にできないかなーと思ったしだいです。

今手元に環境が無いのでおぼろげな記憶だけですが..

だめならやっぱり >>514 に書いたとおり、
せめて excel のクラスIDぐらいはバージョン非依存で取得して、
あとは自分で IDispatch 経由でアクセスするしかないかと..
0518497NGNG
>>514-517
ありがとーございましし。

>xl5jp32.olbと互換性を持たせるなら、IDispatch経由以外ないと

コードレベルでの互換をとるなら、という意味ととってよいでしょうか。
OLBは今ある最新のものを使うとして、それがofficeのバージョンに
依存するかどうか、が一番の焦点だったのですが、問題なさそうですね。

とりあえず、バージョン非互換のクラスID+OLBのインポートで
テストしてみます。
2chで初めて人に感謝しました。
0519sageNGNG
すんません質問です。DelphiでCOMを作る方法を探しています。

Delphi6 PersonalでCOMが作れるか調べていたのですが、
Personalにはウィザードがないようです。ベタに作る手は
あると思うのですが、Googleでもあまり情報がなく。

VC++は歯が立たないので、ほかの言語でCOM作って遊ぼうと
している次第で。WSC、VB6、.Net(C#)は実践済み。
0520デフォルトの名無しさんNGNG
それだけできてVC++で作れないというのが信じられない
0521デフォルトの名無しさんNGNG
hello worldだけとか?<実践済み

WSC(わんだーすわんからー?)/C# がCOMと関係あるとは思えない
0522519NGNG
sage間違いすいません。

>>520
Cの経験がないのです。ニセモノです私(恥)

>>521
ASP/スクリプト環境で使うことを考えていたのです。
作ったものが呼べるとわかればあとは何とかなると思っています。

WSCはWindows Script Componentです。あまり流行ってませんが。
スクリプトのかたまりをCOMとして呼べる代物。
C#/.netはinterop経由でアセンブリをCOMとして呼べます。

VBならActiveX DLLでCOMのこと何も知らずに作れるので、
気楽なものかと思っていたのですが。このスレ読む限り
非常にレベル高そうですね。

ここまで書いてCOMの意味を誤解している気がしてきました。
0523デフォルトの名無しさんNGNG
生COMの実装はカナーリつらいぞ。
知識として知っておくのはいいかもしれんが、自分でやることはないだろうなあ。
DelphiでのやりかたはDelphi関連のスレで聞いた方がいいとおもう。
なんらかのサポートがあったと思うがよく知らない。
0524519NGNG
ありがとうございます。場所を変えて聞いてみます。
0525デフォルトの名無しさんNGNG
今からCOMはかなりお勧めしない。
やるならオートメーションは意図的に省いて
それ以外のアーキテキチャを勉強を勉強すべき。
マーシャリングとかそこらへん。
俺は確信に至った。
IDispatchやIDispatchExなんてのは
明らかに死に行く技術だ。存在価値ゼロ。
0526ななしNGNG
>>525

そこまで読み切れる判断力がうらやましい。(決して皮肉とかじゃないですよ)
VBがやっとな俺の頭脳では、高度な技術の是非までは残念ながら判定できない。(泣
0527sageNGNG
497です。
なんとかうまいことC++からExcelを操作することができるようになりましし。

重ね重ねお礼を申し上げます。

0528ななしNGNG
age
0529デフォルトの名無しさんNGNG
>それ以外のアーキテキチャを勉強を勉強すべき。
君はまず日本語を勉強すべき。
0530ななしNGNG
>>525
>>529
単に手が滑ったか、コピペミス程度のことと思われ。
0531デフォルトの名無しさんNGNG
アーキテキチャ
0532デフォルトの名無しさんNGNG
>Excelを操作することができるようになりましし
こういうのってIDispatchのおかげじゃないの?
0533デフォルトの名無しさんNGNG
このスレでMFCアプリケーションからのMSHTMLの利用方法に関する質問をしてもいいですか?
Web制作板はscriptの話ばっかりで参考にならなくて。
0534デフォルトの名無しさんNGNG
>>533
こんなスレもあるよ。
http://pc.2ch.net/test/read.cgi/tech/982930049/l50
0535533NGNG
>>534 おおう。サンクス。とりあえずそっち全部読んでみるよ。それでもわからんかったら帰ってくるかも。
0536デフォルトの名無しさんNGNG
age
0537デフォルトの名無しさんNGNG
COMってEJBとかと比較されますけど、速度はどうなんでしょうか?単純に比較は
しにくいかもしれないですけどVBとVCで作ったCOMの比較とEJBを比較するとどの
程度の速度差になるのでしょうか?やはりATLなどでVCのCOMがあまりはやらない
のはVBなどでも満足いく速度だから?
0538デフォルトの名無しさんNGNG
>>537
>VBとVCで作ったCOMの比較とEJBを比較するとどの程度の速度差になるのでしょうか?
何の速度差か知らないけど多分、
VC>>>>>VB=>EJB
でしょう。

>やはりATLなどでVCのCOMがあまりはやらないのはVBなどでも満足いく速度だから?

なにが「やはり」なのかはおいといて、
エンドユーザー/開発者から見た場合、COMはVBの為に作られたんだから、
そもそもVCで流行るはずが無いのは当然の結果かと。
VCだけで使うんなら、ただのDLLでもなんでもいいし。
VCでのCOMは「作る」よりも「しかたなく使う」が圧倒的。
速度については、VBは元々遅いから、それで満足する様なやつらからは
文句はでないってだけだと思う。速いマシンに換えるとかね。
それで満足しないやつらは他の手段を模索するでしょう。
0539COMビギナNGNG
どうかご教授を。

タイプライブラリにenumで定義した定数シンボルを、
XMLで記述されたクライアントから参照することは可能でしょうか?

よろしくお願いいたします。
0540COMビギナNGNG
連続カキコでスマソ。

ちょっと誤解を招きそうな表現なので書き直します。

enum定義を含むタイプライブラリを、XMLで利用する際に、
その定義されたシンボルを参照することは可能でしょうか?

よろしくです。
0541デフォルトの名無しさんNGNG
無理
0542COMビギナNGNG
>>541

レスどもです。
やっぱ無理ですか。
別な方法を考えます。
0543デフォルトの名無しさんNGNG
COMってコールバック関数を引数に出来ないんだねぇ。
クライアントにコネクションポイント実装させるのもなあ。
しかし本気でこの型制限にはいらつくよ。何も出来やしねえじゃねえか。
0544デフォルトの名無しさんNGNG
素直にインターフェイスポインタ渡せよ。
0545デフォルトの名無しさんNGNG
まったくだ。コールバック関数よりはるかに柔軟だと思うが。
0546デフォルトの名無しさんNGNG
COMにおける配列参照はいままでも話題になっては
いるのですが、私も文字列の配列をCOM<->VC++クラ
イアント間でやり取りする方法に悩んでいます。

どなたか以下の状況で実装されているソースをご存知
ありませんか?

(1)VC++クライアント側に配列のインスタンスがある。
これはCOleSafeArray

(2)配列はBSTRの一次元構造

(3)COM側で、受け取った配列の参照に対して操作を加える

よろしくお願いします。
0547543NGNG
>>544-545
ピュアなCやC++の環境で使いたい場合どうすんの?
それだとCOMクライアント専用になっちゃうじゃん。
あと質問。
IDLでメンバのオーバーロードを定義すると怒るんだけど。
これって仕様?
だとしたら本当に糞だなCOMって。
0548デフォルトの名無しさんNGNG
古い話してるね〜
COMなんてもうないだろ。
今はEXEだよ。
0549デフォルトの名無しさんNGNG
コールバックされたいクラスの事だよな。
それなら、別にIUnknownから継承をうけて、実装を
いれたとしても、pureなC++でも使えると思うが。
0550名前:デフォルトの名無しさんNGNG
>>548
意味不明。ネタにしても自殺を勧めたくなるほどつまらん。
0551543NGNG
>>549
IUnknownから継承を受けるには
IUnknownの実装を入れなければならないと思うけど。
Release()とかダミーで実装させるの?
0552デフォルトの名無しさんNGNG
真っ当に実装したらいいやん。
0553543NGNG
>>552
それじゃ、COMで実装させることと変わりないじゃん。(笑
MSだって、DirectXとかの例があるし諦めろってことだな。
所詮過渡期の技術か。
0554デフォルトの名無しさんNGNG
>553
でも、COMクライアント専用(この語もなんだか意味不明っぽいが)
というわけではないだろ。
0555デフォルトの名無しさんNGNG
Cからタイプライブラリってどうやって使うんですか?
FreeのBCCでExcelの定数を認識させたいんですが、
さっぱりです。Invokeとかはなんとなくつくれるんですが。
Excelのタイプライブラリの参照例みたいなコードどこかに無いでしょうか
0556デフォルトの名無しさんNGNG
>>553
お前、結局何が不服なんだ?
まぁ過渡期ってのは間違いないだろうな。といってもあるものすべて過渡期と言えるが。
安心しろ。いろんな欠点は.NETで解消されてるだろうから。
0557543NGNG
>>556
俺は、CやC++用のライブラリをCOMで作りたい。
COMの基本的な概念、インターフェイスとか参照カウントなどは
良いと思うのでそれは導入したい。
しかし、マーシャリングやオートメション、スプリクト言語対応
といった機能は別に使わないのでいらない。
だから、そういったものに付随する制限まで課せられるのは
イヤだなと。
それに、C++で使う為のライブラリをC++で作ってるのに、
訳のわからない理由でC++の機能が使えなくなるのは
なんだか納得がいかない。
だったら使うなと言わないで欲しい。
代わりになるものがあるなら別だが。
生のC++や.NETでは代わりにはならない。
0558デフォルトの名無しさんNGNG
>>543
MS社某のお言葉。
0.1%の比率に過ぎないないコンポーネントビルダーは、
99.9%のVBプログラマ向けに、彼らの頭脳では製造不可能な
ものを構築するために存在するんだそうだ。
COMのさまざまな制限はVBあるいはVBA/VBSとの接点による
ものであり、核心部分はC++で記述、フロントをVB/ASP等で
安く作らせるための構図であると。
0559ななしNGNG
>>558

ホンネなんだろうけど・・・正直過ぎ。(苦笑)
0560デフォルトの名無しさんNGNG
あの構成を見てそう思わない奴は居ないと思う。
いまさら言ってるお前って・・・
0561543NGNG
>>543
いや、COM初心者の俺に説明してくれただけだよ。
いや、よくわかりました。
もう愚痴を言うのはやめるよ。
0562デフォルトの名無しさんNGNG
スレッディングモデル絡みの質問なんですが、
ActiveIMM(ActiveX)のCOMサーバをCoIntilaizeEx(NULL,COINIT_MULTITHREADED)で初期化した
スレッド(MTA)で使おうとすると[REGDB_E_IIDNOTREG]なるエラーが出てインターフェイスが
取得できません。
レジストリでそのCLSIDを見ると[ThreadingModel]は[Apartment]でした。
MSのサポート技術情報を見る限りMTA所属のスレッドでも、[Apartment]で登録されている
COMサーバはプロキシ経由で使えそうなのですが、なにか必要な手続きがあるのでしょうか?

ちなみにCoIntilaize()(STA)で初期化したときは正常に取得できます。
0563デフォルトの名無しさんNGNG
IMarshalに答えない仕組みなんじゃない。あるいは、local属性つけてるか。
0564デフォルトの名無しさんNGNG
>>558
ガーン、おれは残り99.9%の中のその他大勢だったのか・・・
0.1%の中にはいるにはどうすればいいんだ・・・(鬱
0565デフォルトの名無しさんNGNG
>>564
0.1%なんて世紀末におけるサウザーぐらいな奴と思われ。
フハハハーとか言って、余興でジジイ殺しちゃうような。
0566デフォルトの名無しさんNGNG
開発言語の格差をCOMで吸収しようという。
ただしオブジェクトはバイナリレベルで提供と。
0567ななしNGNG
age
0568デフォルトの名無しさんNGNG
マーシャリングの質問。
メインSTAで作成したインターフェイスポインタを別のMTAなスレッドで
マーシャリングせずに使ったら、普通に使えてしまったんだがこれって
このまま使っても問題でないんだろうか?
その逆で、MTAなスレッドで取得したインターフェイスポインタをメインSTAで
使用しても同じように問題なく使えました。

ちなみにマーシャリングしようとするとエラーが出て、マーシャリングが
できないんで、そのまま使ってみたんだけど…。

う〜ん、COMは良く分からん(;´д⊂
0569デフォルトの名無しさんNGNG
C++のセマンティクでは使えて当然。STA側のオブジェクトがクリティカルセクションの
保護してなくて、かつ同時に複数のMTAからさわるなら、やめといたが無難。
MTAの生ポインタをSTAが使うのは、別に構わない。
0570デフォルトの名無しさんNGNG
>>568
インターフェイスポインタをどうやって渡したのかによるね。
インターフェイスのメソッドパラメータで渡してるなら、COMが勝手に
マーシャリングしてくれるから問題なし。問題なのはグローバル変数とかで
共有している場合だけ。
0571568NGNG
レスありがとう。

>>569
「アパートメント境界を越えての使用はマーシャリングする必要がある」
って各所に書かれてるんだけど、それは気にしなくてもいいの?
普通のコードと同じ扱いで、そのコードがスレッドセーフ(ThreadingModel=both)なら
そのまま使えて、そうでなければ(ThreadingModel=Apartment)クリティカルセクション
とかで保護すればいいだけ?

>>570
グローバル変数で共有してます…。

そもそも、何故マーシャリングできないのかが不明なんですよね。
マーシャリングするには[HKEY_CLASSES_ROOT\Interface]あたりのレジストリ
に何か登録されてないと駄目とかあります?
0572デフォルトの名無しさんNGNG
>>571
それならマーシャリングが必要。マーシャリングするには、マーシャリング用のコードが必要。
TLBがあるならユニバーサルマーシャラを使う。IDLがあるならMIDLでマーシャリングコードを作れる。

ちなみに、CriticalSectionを使うとかいう問題ではないのでご注意。
0573568NGNG
>>571
ってことは、マーシャリングできないのはマーシャリングコードが無いからか。
ちなみに元発言のMTAなCOMコンポーネントはDirectPlayなんでtlbもidlもないです。
STAの方はidlならあったんだけど、こっちもMS提供な代物なのでいじってもしょうがないしな。
idlがあるからそれを継承してマーシャリング機能だけ追加したものを作るってのは可能?

一番手っ取り早い解決方法は、パフォーマンスを犠牲にして全スレッドをSTAで
やればいいんだろうけど、なんか悔しいし…。

>ちなみに、CriticalSectionを使うとかいう問題ではないのでご注意。
アパートメント境界を越えたアクセスは何かしらの方法でマーシャリングは必須。
ただ、マーシャリングした結果が生ポインタの場合もある。
と言う認識でいいのかな?
0574デフォルトの名無しさんNGNG
>>573
That's correct.
0575569NGNG
なんか、盛り上がってるが……。STA用のコンポーネントの代表はOCX.こいつは、HWNDを
使ったりする。当然、作成したスレッドで動く必要がある。マーシャリングすると、
Windowsメッセージ経由でリクエストされるから、DefWndProcからの呼び出しとなる
ってことは、そのSTAで動くから問題なし。だから、569はちょっと乱暴で、572が正しい。
でも、ユーティリティクラス(引数同志の演算とか。ハッシュ計算するとかさ)をVBで作っちゃった
ような場合(だからSTA)で、TLS使ってないことがわかりきってれば、別にマーシャリング
しなくたって構わないわけ(だが、透過性を無視してる=COMの原理破壊)。
その他、MTAでCoCreateInstanceするとブルブルとか、いろいろあって、おもしろい。
0576569NGNG
>>573
あと、STAだからパフォーマンス犠牲というのは必ずしも正しくはない。並行動作
に意味がないのであれば、STAはひたすら同一スレッドのスタックを使いながら
突っ走るから、実は高速な動作が1番期待可能。(アウトプロセスサーバがSTAだと
リクエスト1個づつしか処理できないから、パフォーマンスは低くなるけど)
0577568NGNG
また、レスありがとう。
まず訂正。前発言の>>571は>>572でした…。

>>573
全部「That's correct.」と解釈してもいいんだろうか…。
説明が無いだけにちょっと不安(^^;

>>569さん
COMの手順に則る限りはマーシャリングは必要なんですね。
「そうでなければ自己責任で…」って感じでしょうか。(^^;
もう一つのパフォーマンス犠牲の話ですが、今回はDiretPlay使っているので
たぶんパフォーマンス落ちます。測っては無いので、どれぐらい落ちるかは不明ですが。
それに、DirectPlayがスレッドを乱立してる感じなんで並行動作してるでしょうし。

う〜ん、どうにも解決手段が見つからない。こう言う時こそMSDNのインシデント使うべきか…。
■ このスレッドは過去ログ倉庫に格納されています