COM難しいよー(T T) (2)&(3)
昨日の「COM難しいよー」問題。
うまくいかない原因は判明しました。
そう、うまくいかない原因は。
成功したテスト用と今作ってるやつと何が違うのか、色々比べてみたら「プロジェクトの種類」が違っていることに今さらながら気づいたわけです。
で、
成功してたのが Win32コンソールプロジェクト
失敗してたのが、MFCプロジェクト
どうやらMFCにはMFCのCOMの実装手順があるみたいです。
細かく言うと、接続ポイントとか、DISPインターフェースをマップしたり他にも何かしなくちゃいけないかもだけど、今日はここで力尽きた...
MFC特有の実装というものはありませんでした。もう一度、シンプルなテスト用のイベントシンクをMFC上で走らせてみたら普通に動いた。
こうなったら確実にできそう&検索でもひっかかりそうな ATLを使ってみようかなと思ったりしてますが、どうなんでしょうね。
危うく、未開拓地であるATLに手を出す所でした...危ない危ない。COMも十分オーバーテクノロジーだったんですが、今回の件で接続ポイント回りには詳しくなれたぞと。
解決はまだしてない。けど
どれが原因か特定できなかったから色々な方向から調べてCOMについてちょっと詳しくなった。仕事は進んで無いけど、経験値は確実に溜まっていってるはず!!
そう考えないとやってけないよ。…だってこの1週間、この問題に掛かりっきりだったし。(T^T)
とにかく、解決するまで色んなアプローチを続けてみます!
というわけで解決しました。
これが原因だった!と1つに絞りきれなかったので、
思い当たる原因を列挙。
最後におさらい
今回のC#でイベントソースオブジェクト、C++でイベントシンクオブジェクトを作る手順を忘れないようにメモ。
C#側(イベントソース)
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)] ←属性に追加
- イベントソースインターフェイスを提供するクラスを実装
[ComSourceInterfaces(typeof(/*イベントソースインターフェイス名*/))]←属性に追加
中間作業(タイプライブラリの作成)
- RegAsm.exeを使ってC#で作ったDLLからTLBファイルを出力する
C++側(イベントシンク)
- タイプライブラリをimport
#import "****.tlb" raw_interfaces_only named_guids
- イベントソースインターフェイスを実装
あとはCOMの流儀に従って、、、
- コンポーネントをCoCreateInstance()
- IConnectionPointContainerをQueryInterface()
- IConnectionPointをFindConnectionPoint()
- 取得したIConnectionPointをAdvise
そして、イベントシンクが必要なくなったら
- 取得したIConnectionPointをUnadvise
参考文献
- COMのイロハを教えてくれた本「Inside COM」(が、絶版らしいです。奇跡的に会社にあってラッキー!)
- 接続ポイントが詳しく書かれていた本「Inside DCOM」(分かり易かった)