ISpRecoResult::Serialize (SAPI 5.4)

Speech API 5.4
Microsoft Speech API 5.4


ISpRecoResult::Serialize creates a serialized copy of the recognition result object. The serialized copy can be saved and later restored using ISpRecoContext::DeserializeResult.

HRESULT Serialize(
   SPSERIALIZEDRESULT   **ppCoMemSerializedResult


[out] Address of a pointer to the SPSERIALIZEDRESULT structure that receives the serialized result information. Call CoTaskMemFree() to free the memory associated with the serialized result object.

Return values

S_OKFunction completed successfully.
E_POINTERppCoMemSerializedResult is an invalid pointer.
E_OUTOFMEMORYExceeded available memory.
FAILED(hr)Appropriate error message.


The following code snippet illustrates the use ISpRecoResult::Serialize to serialize a result and deserialize it back into an ISpRecoContext object.

// Declare local identifiers:
HRESULT                    hr = S_OK;
CComPtr<ISpRecoResult>     cpRecoResult;
CComPtr<ISpRecoResult>     cpRecoResultNew;
CComPtr<IStream>           cpStreamWithResult;
CComPtr<ISpRecoContext>    cpRecoContext;
SPSERIALIZEDRESULT*        pSerializedResult = NULL;
ULONG                      cbWritten = 0;
ULONG                      ulSerializedSize = 0;
LARGE_INTEGER              liseek;
LARGE_INTEGER              li;

// ... Obtain a recognition result object from the recognizer ...
hr = CreateStreamOnHGlobal(NULL, true, &cpStreamWithResult;);

if (SUCCEEDED(hr))
   // Serialize result to memory.
   hr = cpRecoResult->Serialize(&pSerializedResult;);

if (SUCCEEDED(hr))
   // Serialize to a stream pointer.
   hr = cpStreamWithResult->Write(pSerializedResult, pSerializedResult->ulSerializedSize, &cbWritten;);

if (SUCCEEDED(hr))
   // Free the serialized result.
   if (pSerializedResult) ::CoTaskMemFree(pSerializedResult);

   // Commit the stream changes.
   hr = cpStreamWithResult->Commit(STGC_DEFAULT);

if (SUCCEEDED(hr))
   // ... Persist stream to disk, network share, etc ...
   // ... Shutdown application ...
   // ... Restart application and get the persisted stream ...

   // Reset the stream seek pointer to the start before deserialization:
   li.QuadPart = 0;
   hr = cpStreamWithResult->Seek(li, STREAM_SEEK_SET, NULL);

if (SUCCEEDED(hr))
   // Find the size of the stream.
   hr = cpStreamWithResult->Read(&ulSerializedSize;, sizeof(ULONG), NULL);

if (SUCCEEDED(hr))
   // Reset the seek pointer:
   liseek.QuadPart = 0 - sizeof(ULONG);
   hr = cpStreamWithResult->Seek(liseek, STREAM_SEEK_CUR, NULL);

if (SUCCEEDED(hr))
   // Allocate the memory for the result.
   pSerializedResult = (SPSERIALIZEDRESULT*)::CoTaskMemAlloc(ulSerializedSize);

   // Check pSerializedResult in case out "out-of-memory".

   // Copy the stream into a serialized result object.
   hr = cpStreamWithResult->Read(pSerializedResult, ulSerializedSize, NULL);

if (SUCCEEDED(hr))
   // Deserialize result from memory.
   hr = cpRecoContext->DeserializeResult(pSerializedResult, &cpRecoResultNew;);

if (SUCCEEDED(hr))
   // Free the pSerializedResult memory.
   if (pSerializedResult) CoTaskMemFree(pSerializedResult);

// As long as the same engine was used to generate original
// result object, as is now being used, applications can
// now get alternates for the cpRecoResultNew's phrase.