0

我有一个必须使用 COM 插件的 ASP.NET MVC3 网站。为了做到这一点,我需要以某种方式定义一个接口。据我了解(我不是 COM 专家),这可以在 .NET 中完成并使用 tlbexp.exe 或 idl->midl->tlbimp 导出。

我走了第一种方式(使用 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 并重命名了所有内容)。

所以现在我有了这两种方法的 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);

最后一行奇迹般地调用了add_ItemStatusChanged我的 COM 对象上的方法。

在这里我被卡住了,我应该在这种方法中做什么?我目前的实现是:

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”。显然,Advise 期望传递的 COM 对象实现ICOMOutputPluginEvents委托传递的对象没有的连接点接口......我该怎么办?

我是在.NET 端错误地订阅事件还是添加处理程序?

任何帮助如何解决这个问题将不胜感激。

4

1 回答 1

-1

不要在 ASP.Net 的 COM 插件中使用“事件”,只需使用您调用的方法即可。即调用的方法OnEventName而不是事件。

COM 事件只是不适合处理 Web 表单回发。

于 2012-07-04T14:19:36.260 回答