0

所以我尝试调试程序,一旦我进入 Windows API 函数调用,事情就会变得有点疯狂,而且调试这些文件并没有太多帮助,因为我无论如何都无法更改它们。基本上我坚持的是以下两个我可以更改的功能(仅供参考,这是非常旧的代码,程序在 32 位版本中工作,但是当转换为 64 位时,会出现此问题):

void CSalvoPage::AdviseScrollingButtonPanel()
{
    if ( m_SBPCookie == 0 )
    {
        IUnknown * pSinkUnk;
        long * pCookie = &m_SBPCookie;
        m_spSBPControlSink->QueryInterface(IID_IUnknown, (void **) &pSinkUnk);

        if (pSinkUnk != NULL)
        {
            m_SalvoButtons.AddListener(pSinkUnk, pCookie);//here is the problem~~~~
            pSinkUnk->Release();
        }
    }
}

然后我们有执行此操作的 AddListener 调用

void CNvButtonPanel::AddListener(LPUNKNOWN pUnk, long* pCookie)
{
    static BYTE parms[] =
        VTS_UNKNOWN VTS_PI4;
    InvokeHelper(0x16, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
         pUnk, pCookie);
}

我知道 InvokeHelper 函数通过调试抛出异常。我似乎只了解 parms[] 让 InvokeHelper 知道它正在获取哪些类型的参数以及有多少。我查阅了定义,发现事实上

VTS_UNKNOWN = "\x0D" //IUNKNOWN*

VTS_PI4 = "\x43" //a 'long*'

因此,我告诉 InvokeHelper 期望的正确参数类型,所以我不明白为什么每次运行程序时都会在弹出窗口中出现类型不匹配错误......关于我的 InvokeHelper 为什么抛出类型不匹配错误的任何想法?

我试图查看InvokeHelper方法文档,这真的很令人困惑......我所知道的是它抛出了文档中提到的COleException并且从 Invoke 方法返回的 SCODE 是 -2147352571

[id(22), helpstring("method AddListener")] 
            HRESULT AddListener(
                [in] IUnknown * pUnk,
                [out] IUnknown ** pCookie
                );
4

1 回答 1

-1

我能够通过执行 RbMm 建议的方法来解决问题,即更改函数 AddListener 和 RemoveListener 函数以匹配 .idl 文件中声明的类型。

void AddListener(LPUNKNOWN pUnk, LPUNKNOWN* pCookie);
void RemoveListener(LPUNKNOWN pCookie);

这些函数现在正确匹配 .idl 文件中定义的类型

[id(22), helpstring("method AddListener")] 
    HRESULT AddListener(
        [in] IUnknown * pUnk,
        [out] IUnknown ** pCookie
        );

[id(23), helpstring("method RemoveListener")] 
    HRESULT RemoveListener(
        [in] IUnknown * pCookie
        );
于 2017-01-09T18:58:19.380 回答