什么会导致IEnumString->Next()调用调用正确的函数但是将客户端的指针保留为空?一切都是64位(Windows 10)。
数据流:我的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 :(得分:1)
正如Hans Passant指出的那样,片段
if (celt > 1) {
*pceltFetched = i;
}
应该是
if (pceltFetched) {
*pceltFetched = i;
}