Pular para o conteúdo principal
Este tópico se aplica ao FRE para Windows.
Há três maneiras de carregar o objeto Engine no ABBYY FineReader Engine 12. Cada método de carregamento tem suas próprias particularidades, que afetam o uso do objeto em diferentes situações. Os dois primeiros métodos são mais adequados para aplicações interativas que não se destinam ao processamento simultâneo de várias requisições. O terceiro método é mais adequado para soluções de servidor.

Carregando FREngine.dll manualmente e trabalhando com interfaces “naked”

Este é o método padrão para carregar o objeto Engine. Para obter uma referência ao objeto Engine, chame a função InitializeEngine.

Vantagens

Limitações

  • Oferece desempenho máximo.
  • Não requer o registro de FREngine.dll.
public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inicialize estas variáveis com o caminho completo para FREngine.dll, seu ID do projeto do cliente
        // e, se aplicável, o caminho para o arquivo de token da sua Licença Online e a senha da Licença Online
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Carrega a biblioteca FREngine.dll
        dllHandle = LoadLibraryEx(enginePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
           
        try
        {
            if (dllHandle == IntPtr.Zero)
            {
                throw new Exception("Can't load " + enginePath);
            }
            IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
            if (initializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Can't find InitializeEngine function");
            }
            IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
            if (deinitializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Can't find DeinitializeEngine function");
            }
            IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
            if (dllCanUnloadNowPtr == IntPtr.Zero)
            {
                throw new Exception("Can't find DllCanUnloadNow function");
            }
            // Converte os ponteiros em delegates
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Chama a função InitializeEngine 
            // passando o caminho para o arquivo da Licença Online e a senha da Licença Online
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libera a biblioteca FREngine.dll
            engine = null;
            // Exclua todos os objetos antes da chamada a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funções do Kernel32.dll
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // Funções da FREngine.dll
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine(string customerProjectId, string licensePath, 
        string licensePassword, string tempFolder, string dataFolder, bool isSharedCPUCoresMode, 
        ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // variáveis privadas
    private FREngine.IEngine engine = null;
    // Handle de FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Carregando o objeto Engine por meio de COM no processo atual

O Engine é carregado como um servidor em processo no mesmo processo em que a aplicação está em execução. O objeto Engine é carregado usando o objeto InprocLoader, que implementa a interface IEngineLoader.

Vantagens

Limitações

  • Todos os objetos do ABBYY FineReader Engine são totalmente thread-safe e podem ser criados e usados em diferentes threads.
  • Ao trabalhar a partir do apartamento STA principal, o desempenho é o mesmo de quando se trabalha com as naked interfaces. Ao acessar a partir de diferentes threads, pode haver overhead de marshaling, mas ele é desprezível na maioria dos cenários.
  • O registro de FREngine.dll é necessário ao instalar a aplicação final no computador do usuário final.
IEngineLoader engineLoader = new FREngine.InprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false );
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Para registrar FREngine.dll ao instalar sua aplicação no computador do usuário final, use o utilitário regsvr32. Se você estiver em um sistema operacional de 64 bits, a versão de 64 bits do regsvr32 será executada por padrão. Use a seguinte linha de comando:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"

Carregando o objeto Engine por meio de COM em um processo separado

O Engine é carregado como um servidor out-of-process em um processo separado. O objeto Engine é carregado por meio do objeto OutprocLoader, que implementa a interface IEngineLoader.

Vantagens

Limitações

  • Todos os objetos do ABBYY FineReader Engine são totalmente thread-safe. Cada instância do Engine é executada em um processo separado, em paralelo com as demais.
  • É possível organizar um pool de processadores para aproveitar ao máximo a capacidade da CPU do computador.
  • Há uma pequena sobrecarga de marshaling.
  • É necessário registrar o FREngine.dll ao instalar a aplicação final no computador do usuário.
  • Ao trabalhar com contas com permissões limitadas, é necessário conceder as permissões apropriadas.
  • É impossível acessar a imagem de uma página como HBITMAP.
  • Não pode ser usado com Visual Components, pois eles não funcionam com vários processos.
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false);
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Essa forma de carregar o objeto Engine é usada, em particular, no exemplo de código EnginesPool, que fornece uma solução reutilizável para aplicações multithread.
  • As permissões da conta podem ser configuradas usando o utilitário DCOM Config (digitando DCOMCNFG na linha de comando ou selecionando Painel de Controle > Ferramentas Administrativas > Serviços de Componentes). Na árvore do console, localize a pasta Component Services > Computers > My Computer > DCOM Config, clique com o botão direito em ABBYY FineReader Engine 12.5 Loader (Local Server) e clique em Properties. Uma caixa de diálogo será aberta. Clique na guia Security. Em Launch Permissions, clique em Customize e, em seguida, em Edit para especificar as contas que podem iniciar a aplicação.
Observe que, em um sistema operacional de 64 bits, a aplicação DCOM registrada está disponível no console MMC de 32 bits, que pode ser executado com a seguinte linha de comando:
"mmc comexp.msc /32"
  • Para registrar o FREngine.dll ao instalar seu aplicativo no computador do usuário final, use o utilitário regsvr32. Se você estiver usando um sistema operacional de 64 bits, a versão de 64 bits do regsvr32 será executada por padrão. Use a seguinte linha de comando:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Recomendamos usar uma licença de rede tanto para depurar seu aplicativo de servidor quanto para executá-lo.
Além disso, você pode gerenciar a prioridade de um processo host e controlar se ele está em execução usando a interface IHostProcessControl.

Tabela de comparação

A tabela abaixo resume as características dos três métodos de carregamento:
CaracterísticasInterfaces nakedServidor em processoServidor fora do processo
Funciona sem proxy (sem sobrecarga de marshalling)SimHá limitaçõesNão
Funciona em aplicações multithreadHá limitaçõesSimSim
Processos paralelos são possíveis (para soluções de servidor)NãoNãoSim
Não é necessário registrar o FREngine.dllSimNãoNão
Não é necessário configurar permissões de execuçãoSimSimNão
Os objetos podem ser criados usando o operador new. Funciona a partir de scripts.NãoSimSim
Capacidade de acessar uma imagem de página como HBITMAPSimSimNão
Funciona em um processo separado (à prova de falhas, com reciclagem)NãoNãoSim
Pode ser usado com Visual ComponentsSimSimNão

Veja também

Usando o ABBYY FineReader Engine em aplicativos de servidor com múltiplas threads