Saltar al contenido principal
Este tema se aplica a FRE para Windows.
Hay tres formas de cargar el objeto Engine en ABBYY FineReader Engine 12. Cada método de carga tiene sus propias particularidades, que afectan al uso del objeto en distintas circunstancias. Los dos primeros métodos son los más adecuados para aplicaciones interactivas que no están pensadas para procesar varias solicitudes simultáneamente. El tercer método es el más adecuado para soluciones de servidor.

Carga manual de FREngine.dll y trabajo con interfaces “directas”

Este es el método estándar para cargar el objeto Engine. Para obtener una referencia al objeto Engine, llame a la función InitializeEngine.

Ventajas

Limitaciones

  • Ofrece el máximo rendimiento.
  • No requiere registrar FREngine.dll.
public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inicializa estas variables con la ruta completa a FREngine.dll, tu Customer Project ID
        // y, si corresponde, la ruta a tu archivo de token de licencia en línea y la contraseña de la licencia en línea
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Carga la 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");
            }
            // Convierte los punteros en delegados
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Llama a la función InitializeEngine 
            // y pasa la ruta al archivo de licencia en línea y la contraseña de la licencia en línea
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libera la biblioteca FREngine.dll
            engine = null;
            // Elimina todos los objetos antes de llamar a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funciones de 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);
    // Funciones de 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();
    // Variables 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;
}

Carga del objeto Engine mediante COM en el proceso actual

El Engine se carga como un servidor en proceso dentro del mismo proceso en el que se ejecuta la aplicación. El objeto Engine se carga mediante el objeto InprocLoader, que implementa la interfaz IEngineLoader.

Ventajas

Limitaciones

  • Todos los objetos de ABBYY FineReader Engine son completamente seguros para subprocesos y pueden crearse y usarse en distintos subprocesos.
  • Al trabajar desde el apartamento STA principal, el rendimiento es el mismo que al trabajar con las interfaces directas. Al acceder desde distintos subprocesos, puede producirse una sobrecarga de marshaling, pero es insignificante en la mayoría de los casos.
  • Es necesario registrar FREngine.dll al instalar la aplicación final en el equipo del usuario final.
IEngineLoader engineLoader = new FREngine.InprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false );
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Para registrar FREngine.dll al instalar su aplicación en un equipo de usuario final, use la utilidad regsvr32. Si está en un sistema operativo de 64 bits, la versión de 64 bits de regsvr32 se ejecutará de forma predeterminada. Use la siguiente línea de comandos:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"

Carga del objeto Engine mediante COM en un proceso independiente

El Engine se carga como un servidor fuera del proceso en un proceso independiente. El objeto Engine se carga mediante el objeto OutprocLoader, que implementa la interfaz IEngineLoader.

Ventajas

Limitaciones

  • Todos los objetos de ABBYY FineReader Engine son completamente seguros para subprocesos. Cada instancia del Engine se ejecuta en un proceso independiente en paralelo con las demás.
  • Se puede organizar un pool de procesadores para aprovechar al máximo la capacidad de la CPU del equipo.
  • Hay una pequeña sobrecarga de marshaling.
  • Es necesario registrar FREngine.dll al instalar la aplicación final en el equipo del usuario final.
  • Al trabajar con cuentas con permisos limitados, se deben conceder los permisos necesarios.
  • Es imposible acceder a una imagen de página como HBITMAP.
  • No puede usarse con Visual Components, ya que no funcionan con varios procesos.
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false);
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Esta forma de cargar el objeto Engine se usa, en particular, en el ejemplo de código EnginesPool, que proporciona una solución reutilizable para aplicaciones multihilo.
  • Los permisos de la cuenta pueden configurarse con la utilidad DCOM Config (ya sea escribiendo DCOMCNFG en la línea de comandos o seleccionando Panel de control > Herramientas administrativas > Servicios de componentes). En el árbol de la consola, localice la carpeta Component Services > Computers > My Computer > DCOM Config, haga clic con el botón derecho en ABBYY FineReader Engine 12.5 Loader (Local Server) y luego en Propiedades. Se abrirá un cuadro de diálogo. Haga clic en la pestaña Seguridad. En Permisos de inicio, haga clic en Personalizar y, a continuación, en Editar para especificar las cuentas que pueden iniciar la aplicación.
Tenga en cuenta que, en un sistema operativo de 64 bits, la aplicación DCOM registrada está disponible en la consola MMC de 32 bits, que puede ejecutarse mediante la siguiente línea de comandos:
"mmc comexp.msc /32"
  • Para registrar FREngine.dll al instalar su aplicación en un equipo de usuario final, use la utilidad regsvr32. Si usa un sistema operativo de 64 bits, se ejecutará de forma predeterminada la versión de 64 bits de regsvr32. Use la siguiente línea de comandos:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Recomendamos que utilice una licencia de red tanto para depurar su aplicación de servidor como para ejecutarla.
Además, puede administrar la prioridad de un proceso anfitrión y controlar si sigue en ejecución mediante la interfaz IHostProcessControl.

Tabla comparativa

La siguiente tabla resume las características de los tres métodos de carga:
CaracterísticasInterfaces directasServidor en procesoServidor fuera del proceso
Funciona sin proxy (sin sobrecarga de marshaling)Hay limitacionesNo
Funciona en aplicaciones multihiloHay limitaciones
Permite procesos en ejecución en paralelo (para soluciones de servidor)NoNo
No es necesario registrar FREngine.dllNoNo
No es necesario configurar permisos de ejecuciónNo
Los objetos se pueden crear con el operador new. Funciona desde scripts.No
Permite acceder a la imagen de una página como HBITMAPNo
Funciona en un proceso independiente (aislamiento ante fallos, reciclado)NoNo
Se puede usar con Visual ComponentsNo

Consulte también

Uso de ABBYY FineReader Engine en aplicaciones de servidor multihilo