2012-02-20 20 views
0

私は.NETのライブラリを持っています。これは、非同期操作を含むCOM相互運用性のために公開する必要があります。したがって、私はイベントを実装する必要があります。C++の.NETイベントを実装する最も簡単な方法

[ComVisible(true)] 
[Guid("...")] 
[ClassInterface(ClassInterfaceType.None)] 
[ComSourceInterfaces(typeof(IClass1Event))] 
public class Class1: IClass1 
{ 
    public delegate Int32 IntIntFunc(Int32 arg); 
    public event IntIntFunc Event; 

    public Int32 RaiseEvent(Int32 param) 
    {...} 
} 

[ComVisible(true)] 
[Guid("...")] 
public interface IClass1 
{ 
    Int32 RaiseEvent(Int32 param); 
} 

[ComVisible(true)] 
[Guid("...")] 
public interface IClass1Event 
{ 
    Int32 Event(Int32 param); 
} 

しかし、私はC++イベントシンクの実装に問題があります。 私は様々な例を用意していますIConnectionPoint::Adviseから単なる "VBを使う"までの範囲ですが、それらを実装しようとするあらゆる種類の問題を抱えています(VBでは使用できません) - ATLが私にはAddRef 、または私は心配してVTablesを理解できません(私は非常に基本的にCフレームワークに精通しています、残念ながら)。 私はどのフレームワークが望ましいかについての情報がなく、そのクライアントだけがC++です。

私の質問は、.NETイベントをC++に公開するための最善の方法とは何なのでしょうか。その結果、テストシンクを実装する最も簡単な方法は何ですか?

P .:実際にはIDispatchにするにはイベントインターフェイスが必要ですか?

+0

あなたが唯一のC++であなたのCOMオブジェクトを使用する場合は、あなたがJavaScriptや他のスクリプト言語から同じオブジェクトを使用して起動した場合しかし、あなたが、あなたのイベントのインタフェース 'IDispatch'を行う必要はありません。 – Justin

+1

イベントハンドラのための多くのC++実装がありますが、私はboost.signals2をお勧めします(用語は異なりますが、何が何であるかを説明するのは非常に良いです、http://www.boost.org/doc/ libs/1_48_0/doc/html/signals2.html) –

答えて

1

COMに精通していれば、C++のvtableは非常に簡単です。マイクロソフトでは、それらが完全に同一であると定義しました。つまり、class IUnknownのMSVC++ vtableは、interface IUnknownのCOM機能テーブルと同じバイナリです。

今、あなたはIConnectionPoint::Adviseにつまずいているようです。それは理解できる。あなたが実装しなければならないインターフェースのようですが、そうではありません。イベントソースによって実装されるインターフェイスです。使用するシンクをソースに伝えるために使用します。

何が起こるかを確認するには、ダミーのIUnknownオブジェクトをIConnectionPoint::Adviseに渡し、IUnknown::QueryInterfaceにブレークポイントを設定します。もちろん、GUIDによるIClass1Eventのイベントソースクエリが表示されます。これを実装すると、IUnknown::QueryInterfaceから返すことができます。

IDispatchインターフェイスを実装する必要はありません。 .Netはなくてもできます。それはそれを必要とする古いVisual Basic 6です。これは、VB6は弱く型付けされており、後でバインドする必要があるからです。

More reading material.

+0

アドバイスをいただきありがとうございます。私は 'IConnectionPoint'に精通していましたが、私の本当の問題はVC++のイベントシンクオブジェクトの自動実装でした。私は最終的に** ATL **オブジェクトテンプレートと**デュアルインターフェイス**でそれを行うことができました。私のソリューションは完全にひどいので最適ではないので、私はまだ私自身の質問にはまだ答えられません... –

関連する問題