2012-02-20 47 views
0

我有一個.NET庫,需要公開COM互操作,包括一些異步操作。因此,我需要實施活動。從C#實現事件看起來很簡單,因爲:爲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 ,或者我無法理解我的想法(不幸的是,我非常熟悉C框架)。 我沒有關於什麼框架是可取的信息,只有客戶端是C++。

所以我的問題是:什麼是將.NET事件暴露給C++的最尖端方式,因此,實現測試接收器的最簡單方法是什麼?

P.S .:我真的需要一個事件接口來做IDispatch嗎?

+0

你並不需要讓你的事件接口'IDispatch'如果你只在C++中使用COM對象,但是你,如果你開始使用從JavaScript或其他腳本語言相同的對象做。 – Justin 2012-02-20 11:17:07

+1

事件處理程序有很多C++實現,我可以推薦的是boost.signals2(術語不同,但介紹很好解釋什麼是,doc在那裏:http://www.boost.org/doc/ libs/1_48_0/doc/html/signals2.html) – 2012-02-20 12:11:47

回答

1

如果您熟悉COM,C++ vtables非常容易。微軟幾乎將它們定義爲相同的。也就是說,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's,我真正的問題是在VC++中自動實現事件接收器對象。我最終設法用一個** ATL **對象模板和一個**雙重界面**來做到這一點。由於我的解決方案非常糟糕,絕不是最佳選擇,我仍然無法自己回答我的問題...... – 2012-02-28 09:10:12

相關問題