Dostarczanie wywołań zwrotnych dla usług ELS
Jeśli aplikacja używa operacji asynchronicznych na potrzeby rozpoznawania tekstu, musi udostępnić funkcję wywołania zwrotnego dla usługi ELS do użycia. Funkcja wywołania zwrotnego jest oparta na prototypie MappingCallbackProc.
W temacie Requesting Text Recognition (Żądanie rozpoznawania tekstu) opisano, w jaki sposób aplikacja może żądać asynchronicznego rozpoznawania tekstu z usługi ELS. W poniższym przykładzie pokazano aplikację, która wykonuje asynchroniczne wywołanie MappingRecognizeText. Funkcja wywołania zwrotnego na potrzeby rozpoznawania tekstu jest nazywana RecognizeCallback. Należy pamiętać, że aplikacja musi upewnić się, że zbiór właściwości, tekst wejściowy, opcje i usługa pozostają poprawne aż do zakończenia wykonywania funkcji zwrotnej. Ponadto aplikacja musi upewnić się, że MappingFreePropertyBag jest wywoływana natychmiast po użyciu torby przez funkcję wywołania zwrotnego.
Notatka
Może być dobrym pomysłem, aby twoja aplikacja używała funkcji zwrotnej do zwolnienia zasobów po zakończeniu ich przetwarzania lub kopiowania.
#include <windows.h>
#include <stdio.h>
#include <elscore.h>
#include <elssrvc.h>
#define USER_TEXT ( \
L"Skip This is a simple sentence. " \
L"\x0422\x0445\x0438\x0441 \x0438\x0441 \x0415\x043d\x0433\x043b\x0438\x0441\x0445.")
#define USER_TEXT_SKIP (5)
int __cdecl main();
HRESULT CallMappingRecognizeText(PMAPPING_SERVICE_INFO pService);
void RecognizeCallback(
PMAPPING_PROPERTY_BAG pBag,
LPVOID data, DWORD dwDataSize,
HRESULT Result);
int __cdecl main()
{
MAPPING_ENUM_OPTIONS EnumOptions;
PMAPPING_SERVICE_INFO prgServices = NULL;
DWORD dwServicesCount = 0;
HRESULT hResult;
ZeroMemory(&EnumOptions, sizeof (MAPPING_ENUM_OPTIONS));
EnumOptions.Size = sizeof (MAPPING_ENUM_OPTIONS);
// Using the Language Auto-Detection GUID to enumerate LAD only:
EnumOptions.pGuid = (GUID *)&ELS_GUID_LANGUAGE_DETECTION;
hResult = MappingGetServices(&EnumOptions, &prgServices, &dwServicesCount);
if (SUCCEEDED(hResult))
{
hResult = CallMappingRecognizeText(&prgServices[0]);
if (SUCCEEDED(hResult))
{
printf("Calling the service %ws has succeeded!\n",
prgServices[0].pszDescription);
}
else
{
printf("Calling the service %ws has failed, failure = 0x%x!\n",
prgServices[0].pszDescription, hResult);
}
MappingFreeServices(prgServices);
}
return 0;
}
HRESULT CallMappingRecognizeText(PMAPPING_SERVICE_INFO pService)
{
MAPPING_PROPERTY_BAG bag;
MAPPING_OPTIONS Options;
HRESULT hResult;
HANDLE SyncEvent;
DWORD dwWaitResult;
SyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (SyncEvent == NULL)
{
hResult = E_FAIL;
}
else
{
ZeroMemory(&bag, sizeof (MAPPING_PROPERTY_BAG));
bag.Size = sizeof (MAPPING_PROPERTY_BAG);
ZeroMemory(&Options, sizeof (MAPPING_OPTIONS));
Options.Size = sizeof (MAPPING_OPTIONS);
Options.pfnRecognizeCallback = (PFN_MAPPINGCALLBACKPROC)RecognizeCallback;
Options.pRecognizeCallerData = &SyncEvent;
Options.dwRecognizeCallerDataSize = sizeof (HANDLE);
// MappingRecognizeText's dwIndex parameter specifies the first
// index inside the text from where the recognition should start.
// We pass USER_TEXT_SKIP, thus skipping the "Skip " part
// of the input string.
hResult = MappingRecognizeText(pService, USER_TEXT, wcslen(USER_TEXT), USER_TEXT_SKIP, &Options, &bag);
if (SUCCEEDED(hResult))
{
// We are using an event to synchronize our waiting for the call to end,
// because some objects have to be valid till the end of the callback call:
// - the input text
// - the property bag
// - the options
// - the service
dwWaitResult = WaitForSingleObject(SyncEvent, INFINITE);
if (dwWaitResult != WAIT_OBJECT_0)
{
hResult = E_FAIL;
}
}
CloseHandle(SyncEvent);
}
return hResult;
}
void RecognizeCallback(PMAPPING_PROPERTY_BAG pBag, LPVOID data, DWORD dwDataSize, HRESULT Result)
{
HANDLE SyncEvent;
WCHAR * p;
UNREFERENCED_PARAMETER(dwDataSize);
if (SUCCEEDED(Result))
{
for (p = (WCHAR *)pBag->prgResultRanges[0].pData; *p; p += wcslen(p) + 1)
{
printf("%ws\n", p);
}
MappingFreePropertyBag(pBag);
}
SyncEvent = *((HANDLE *)data);
SetEvent(SyncEvent);
}
Tematy pokrewne
-
Mapowanie FreePropertyBag