我有一個ASP.NET MVC3網站必須使用COM插件。爲了做到這一點,我需要以某種方式定義一個接口。據我所知(我不是一個COM專家),這可以在.NET中完成,並用tlbexp.exe或idl-> midl-> tlbimp導出。基於COM的.net插件框架
我走了第一條路(用tlbexp)。我也嘗試過IDL,但無濟於事(出於某種原因可以將實現COM對象轉換回.NET中的tlbimp接口)。
此方案將是簡單的,如果我的界面沒有它的事件:
[ComVisible(true)]
[Guid("EFCFB783-0225-4D45-94CB-9A26B7CC19AF")]
public delegate void ItemStatusChanged(string itemGuid, string itemStatus);
[ComVisible(true)]
[Guid("35202AE5-392D-4015-993D-29966DA5DE31")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ICOMOutputPlugin
{
void Method1(string arg);
void Method2(string arg);
event ItemStatusChanged ItemStatusChanged;
}
[ComVisible(true)]
[Guid("93862C43-503C-4C96-9BAE-944F1087AB77")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ICOMOutputPluginEvents
{
void ItemStatusChanged(string itemGuid, string itemStatus);
}
我這個出口與tlbexp.exe到TLB和註冊regtlibv12的.TLB。 只有這個類型的庫將被插件開發者用來導入接口。
現在我有一個C++項目,這將是一個插件,我在VS2010新的簡單的ATL對象添加和更改IDL到:
importlib("stdole2.tlb");
importlib("MyExp.tlb");
[
uuid(E09BC67A-4192-4CA3-8FD0-5CBFC69B43AC)
]
coclass DumpToFileOutputPlugin
{
[default] interface ICOMOutputPlugin;
[default, source] dispinterface ICOMOutputPluginEvents;
};
我的第一個問題就在這裏了,由於某種原因,我不能通過類嚮導添加連接點'正常方式'。當我將它指向我的MyExp.tlb時,它根本不顯示任何源接口。所以我手動(使用另一個.tlb並重命名所有內容)。
所以現在我有這2種方法的COM對象:
STDMETHOD(add_ItemStatusChanged)(_ItemStatusChanged* value);
STDMETHOD(remove_ItemStatusChanged)(_ItemStatusChanged* value);
在.NET方面的插件管理器實例這樣的插件:
Type type = Type.GetTypeFromProgID(progID);
comObject = Activator.CreateInstance(type) as ICOMOutputPlugin;
comObject.ItemStatusChanged += (guid, status) => ItemStatusChanged(guid, status);
最後一行奇蹟般地調用我的COM對象上的方法add_ItemStatusChanged
。
在這裏,我卡住了,我應該用什麼方法在這種方法?我目前的實現是:
HRESULT CDumpToFileOutputPlugin::add_ItemStatusChanged(_ItemStatusChanged* value)
{
DWORD cookie;
HRESULT ret = Advise(value, &cookie);
_com_error err(ret);
LPCTSTR errMsg = err.ErrorMessage();
return ret;
}
RET = CONNECT_E_CANNOTCONNECT(0x80040202)和ERRMSG說: 「到IDispatch錯誤#2」。 顯然建議期望傳遞的COM對象實現委託傳遞對象的連接點接口ICOMOutputPluginEvents
不......我該怎麼辦?
我是否訂閱了.NET上的事件錯誤或添加處理程序?
任何幫助如何解決這個將不勝感激。
我的問題與ASP.NET無關,它只是一個COM Interop問題,任何其他.net應用程序都會解釋這個問題 – Bond
@Bond,您錯過了這一點。你不需要事件。你只是不需要它們,所以通過不使用事件來避免COM互操作問題。只需具有EVENT-LIKE NAMES的功能,並在事件發生時調用它們。這是因爲COM事件是不同的BEASTS,並且正如你剛纔所瞭解的那樣,很難在ASP.NET中建立連接。 – Ben
事實上,tlbexp將事件導出到add/remove方法對中,並且在我訂閱.NET端事件時調用這些方法,這讓我認爲必須有某種方法才能使其工作。 – Bond