2016-11-29 5 views
0

Was würde einen IEnumString->Next()-Aufruf verursachen, um die richtige Funktion aufzurufen aber den Zeiger des Clients leer zu lassen? Alles ist 64bit (Windows 10).COM out-ptr bleibt Null in Client

Datenfluss: Meine DLL ->MSSpellCheckingHost -> Client

In my code (Github link) alles klar geht. Die Zuordnung und Kopie sehen gut aus. Aber der Kunde sieht einen Null-Zeiger, aber nur, wenn sie über ISpellCheckProvider->Suggest(); kommt es funktioniert gut über ISpellCheckProviderFactory->get_SupportedLanguages()

Snippet von 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; 
}; 

Wie gezeigt, gibt es viele Debug-Drucke, weil ein Debugger zu MSSpellCheckingHost Befestigung ist ziemlich lästig, und sie ergeben die erwartete Ausgabe von zB:

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

..., die der Ausgangszeiger zeigt gesetzt wird und die Daten darauf zu korrigieren. Und es funktioniert, wenn SupportedLanguages aufgerufen wird - das den richtigen Wert an den Enumerator zurückgibt und der Wert verwendet wird, so dass es nicht null sein konnte. Aber wenn Suggest() verwendet wird, schaffen es die Ergebnisse nicht.

Alle anderen Funktionen, die Strukturen zurückgeben, die über CoTaskMemAlloc zugewiesen wurden, funktionieren ebenfalls, sodass der Host insgesamt funktionsfähig erscheint, außer in diesem einen Fall.

+0

Was meinen Sie mit "verlassen die Client-Zeiger null" sein sollte? Der Client sollte einen Zeiger auf ein Array von Zeigern übergeben, das mit "Next" ausgefüllt wird. Ist das der Client-Code? –

+0

@ Cheersandhth.-Alf, yup, Client ist MS eigene Probe. Es geht in der richtigen Sache (kocht bis zu einem wchar_t **), aber es bleibt null, wenn "Next" zurückkehrt. Ich kann den Pfad nicht sogar debuggen, da das MSSpellCheckingHost über keine Debugsymbole verfügt. Ich habe versucht, ein bisschen in die Ausgabe zu setzen, nur um zu sehen, ob ich damit herumhantieren könnte, aber nichts schafft es in diesem einen Anruf. –

+0

Sie müssen * immer * 'pceltFetched' zuweisen. 0 ist ein korrekter Wert für "es gibt keine Vorschläge". –

Antwort

1

Wie Hans Passant wies darauf hin, das Snippet

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

statt

if (pceltFetched) { 
     *pceltFetched = i; 
    } 
Verwandte Themen