2016-11-29 11 views
0

什麼會導致IEnumString->Next()調用調用正確的函數,但將客戶端的指針留空?一切都是64位(Windows 10)。COM out-ptr在客戶端中保持爲空

數據流:我的DLL - >MSSpellCheckingHost - >客戶端

In my code (Github link)一切正常。分配和複製看起來很好。但客戶看到一個空指針,但只能通過ISpellCheckProvider->Suggest();到來時,它通過ISpellCheckProviderFactory->get_SupportedLanguages()

段從EnumString.hpp正常工作:

template<typename String> 
inline void CoCopyWString(const String& in, PWSTR* out) { 
    debugp p(__FUNCTION__); 
    p(in, static_cast<void*>(*out)); 
    *out = reinterpret_cast<LPWSTR>(CoTaskMemAlloc(sizeof(wchar_t)*(in.size() + 1))); 
    std::copy(in.begin(), in.end(), *out); 
    (*out)[in.size()] = 0; 
    p(std::wstring(*out), static_cast<void*>(*out)); 
} 

class EnumString : public IEnumString { 
public: 
... 
    IFACEMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) { 
     debugp p(__FUNCTION__); 
     p(celt); 
     HRESULT hr = S_FALSE; 

     ULONG i = 0; 
     for (; i < celt && current < strings.size(); ++i, ++current) { 
      p(i, current); 
      CoCopyWString(strings[current], rgelt+i); 
      p(static_cast<void*>(rgelt + i), static_cast<void*>(rgelt[i])); 
     } 

     if (celt > 1) { 
      *pceltFetched = i; 
     } 
     if (i == celt) { 
      hr = S_OK; 
     } 

     return hr; 
    } 
... 
private: 
    std::vector<std::wstring> strings; 
    ULONG current = 0; 
}; 

如圖所示,還有很多調試版畫,因爲安裝調試器MSSpellCheckingHost是非常煩惱,他們產生的預期輸出如:

EnumString::Next 
    1 
    0 0 
    CoCopyWString 
     i-llu 0000000000000000 
     i-llu 000001CC35682AE0 
    ~CoCopyWString 
    000001CC356A1F50 000001CC35682AE0 
~EnumString::Next 

...它顯示輸出指針被設置並且指向的數據是正確的。並且它在SupportedLanguages被調用時起作用 - 它將正確的值返回給枚舉器,並使用該值,因此它不能爲空。但是,當使用Suggest()時,結果無法完成。

返回通過CoTaskMemAlloc分配的結構的所有其他函數也可以正常工作,因此除了這種情況外,主機總體上看起來很有用。

+0

你是什麼意思「離開了客戶的指針空」是什麼意思?客戶端應該將一個指針傳遞給一個由「Next」填充的指針數組。客戶端代碼是做什麼的? –

+0

@ Cheersandhth.-Alf,yup,客戶是MS自己的樣本。它傳遞正確的東西(歸結爲一個wchar_t **),但是當'Next'返回時它仍然爲空。我甚至無法調試通過的路徑,因爲MSSpellCheckingHost沒有可用的調試符號。我確實嘗試在輸出中設置任何位以查看是否可以擺弄它,但在一次調用中沒有任何結果。 –

+0

您必須*總是*分配'* pceltFetched'。 0是「沒有建議」的正確值。 –

回答

1

正如漢斯帕桑特指出,該段

if (celt > 1) { 
     *pceltFetched = i; 
    } 

應改爲

if (pceltFetched) { 
     *pceltFetched = i; 
    }