0

我正在编写一个通过 COM 公开许多方法的 BHO。它们中的大多数工作正常,但最近添加的 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 来创建类似的行为,我尝试通过定义要实现的新接口、更改 guid、增加类型库版本等来“重置”类型库。所有这些都导致在根本不可调用的方法中。

据我在这里和 MSDN 上所做的研究可以看出,我走在正确的轨道上。如何成功地将新方法添加到我的 COM 类,以便可以在我的 BHO 对象上调用它们?BHO 尚未发布,因此界面尚未确定。

4

1 回答 1

0

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

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

首选项.h

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

身份证:

[
    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;
    };
}
于 2014-04-10T23:01:30.907 回答