为什么不能从文档中调用新添加的COM方法?

时间:2014-04-08 19:08:24

标签: c++ com bho idl coclass

我正在编写一个BHO,它通过COM公开了许多方法。他们中的大多数工作正常,但最近添加的2个表现出奇怪的行为。

当从页面上的JavaScript调用时,新添加的方法"返回"未定义,而不是抛出方法或属性不存在的异常,因此对象至少知道方法在其上,但从不执行它们。

bho.h

class ATL_NO_VTABLE CBho :
public IObjectWithSite,
public IDispatchImpl<IBho, &IID_IBho>,
public IOleCommandTarget
{
public:
    STDMETHOD(DeletePreference)(BSTR prefName);
};

bho.cpp:

STDMETHODIMP CBho::DeletePreference(BSTR prefName) {
    //some code that interacts with localStorage
    return S_OK;
}

我的IDL:

[
    object,
    uuid(/*uuid/*),    
    dual,
    nonextensible,
    helpstring("IBho Interface"),
    pointer_default(unique)
]
interface IBho : IDispatch{
    ...
    [id(5), helpstring("method DeletePreference")] HRESULT DeletePreference([in] BSTR prefName);
};

[
    uuid(/*uuid*/),
    version(1.0),
    helpstring("Bho1.0 Type Library")
]
library MyBhoLib
{
    importlib("stdole2.tlb");
    [
        uuid(36BA1FA3-144A-4A1A-BE62-8301C4E4ADEF),     
        helpstring("Bho Class")
    ]
    coclass BhoSite
    {
        [default] interface IBho;
    };
}

我注意到可以通过更改ID来创建类似的行为,我已经尝试过&#34;重置&#34;类型库通过定义要实现的新接口,更改guid,递增类型库版本等等。所有这些导致方法根本不可调用。

据我所知,我在这里以及在MSDN上花费的研究表明,我已走上正轨。如何成功将新方法添加到我的COM类中,以便可以在我的BHO对象上调用它们? BHO还没有发布,所以界面还没有一成不变。

1 个答案:

答案 0 :(得分:0)

我能够解决这个问题,但不是我完全理解的方式。似乎IBho接口仅支持IDL公开的4种方法。之后,调用方可以看到这些方法,但不会执行。我不知道为什么会这样,并且还没有找到任何解决这个问题的文档。

为了解决这个问题,我简单地创建了一个新的COM类,用于管理存储并通过IDL和注册过程将其暴露给COM。这使我能够扩展与存储相关的API以包含DeletePreference方法,以及向BHO添加其他请求的功能。无论如何,这可能是更好的编码实践。现在看来是这样的:

Preferences.h

class CPreferences :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CPreferences, &CLSID_Preferences>,
    public IDispatchImpl<IPreferences , &IID_IPreferences >
{
    ...
    /implementation
};

IDL:

[
    object,
    uuid(/*uuid/*),    
    dual,
    nonextensible,
    helpstring("IBho Interface"),
    pointer_default(unique)
]
interface IBho : IDispatch{
    ...
    [id(4), helpstring("method DoSomeThing")] HRESULT DoSomeThing([in] BSTR prefName);
};

[
    object,
    uuid(/*uuid/*),    
    dual,
    nonextensible,
    helpstring("IPreferences Interface"),
    pointer_default(unique)
]
interface IPreferences : IDispatch{
    ...
    [id(3), helpstring("method DeletePreference")] HRESULT DeletePreference([in] BSTR prefName);
};

[
    uuid(/*uuid*/),
    version(1.0),
    helpstring("Bho1.0 Type Library")
]
library MyBhoLib
{
    importlib("stdole2.tlb");
    [
        uuid(36BA1FA3-144A-4A1A-BE62-8301C4E4ADEF),     
        helpstring("Bho Class")
    ]
    coclass BhoSite
    {
        [default] interface IBho;
    };
    [
        uuid(uuid),     
        helpstring("Preferences Class")
    ]
    coclass Preferences 
    {
        [default] interface IPreferences;
    };
}