首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

ATL 集合枚舉器 Bug 修正:IEnumOnSTLImpl::Next 參數傳遞錯誤

     編輯:關於VC++

承接《組件對象模型與ATL實現》一文,發現 ATL 內建 atlcom.h 中 IEnumOnSTLImpl::Next 實現存在一處關鍵 Bug,導致自定義 Copy Policy 無法正確工作。本文給出精確修正點。

問題定位

原始碼 (atlcom.h) 中:

hr = Copy::copy(pelt, &*m_iter); // 錯誤:傳遞了雙重指標/引用

m_iter 為 STL 迭代器,*m_iter 即元素值 (如 CComPtr<T>),&*m_iter 取其位址導致類型不匹配。

修正後代碼

hr = Copy::copy(pelt, *m_iter); // 正確:直接傳遞元素值

完整修正函數 (供替換 atlcom.h 或自建 atlcom0.h)

template <class Base, const IID* piid, class T, class Copy, class CollType>
STDMETHODIMP IEnumOnSTLImpl<Base, piid, T, Copy, CollType>::Next(
    ULONG celt, T* rgelt, ULONG* pceltFetched)
{
    if (rgelt == NULL || (celt != 1 && pceltFetched == NULL))
        return E_POINTER;
    if (pceltFetched != NULL) *pceltFetched = 0;
    if (m_pcollection == NULL) return E_FAIL;

    ULONG nActual = 0;
    HRESULT hr = S_OK;
    T* pelt = rgelt;

    while (SUCCEEDED(hr) && m_iter != m_pcollection->end() && nActual < celt)
    {
        // 關鍵修正:移除多餘的 &
        hr = Copy::copy(pelt, *m_iter); 

        if (FAILED(hr))
        {
            while (rgelt < pelt) Copy::destroy(rgelt++);
            nActual = 0;
        }
        else
        {
            pelt++; m_iter++; nActual++;
        }
    }

    if (SUCCEEDED(hr))
    {
        if (pceltFetched) *pceltFetched = nActual;
        if (nActual < celt) hr = S_FALSE;
    }
    return hr;
}

應用方式

  1. 複製 atlcom.h 為 atlcom0.h,套用上述修正。
  2. 在 stdafx.h 中,於包含 atlcom0.h 前定義宏啟用 0-based 索引 (可選):
#define ITEM_INDEX_0_BASED
#include "atlcom0.h" // 替換原 atlcom.h

此修正已驗證可解決自定義集合類 (如文中 _CopyVariantFromAdaptItf, _CopyItfFromAdaptItf) 的枚舉失效問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved