Vai al contenuto principale
Questo argomento si applica a FRE per Windows.
Esistono tre modi per caricare l’oggetto Engine in ABBYY FineReader Engine 12. Ciascun metodo di caricamento presenta caratteristiche specifiche che ne influenzano l’uso in diverse circostanze. I primi due metodi sono più indicati per le applicazioni interattive che non prevedono l’elaborazione simultanea di più richieste. Il terzo metodo è invece più adatto alle soluzioni server.

Caricamento manuale di FREngine.dll e utilizzo di interfacce “naked”

Questo è il metodo standard per caricare l’oggetto Engine. Per ottenere un riferimento all’oggetto Engine, chiamare la funzione InitializeEngine.

Vantaggi

Limitazioni

  • Garantisce le massime prestazioni.
  • Non richiede la registrazione di FREngine.dll.
  • Impone restrizioni per l’uso con applicazioni multithread (vedere Uso di ABBYY FineReader Engine in applicazioni server multithread).
  • Quando si lavora con linguaggi di alto livello (ad esempio .NET), è necessario utilizzare strumenti di basso livello per caricare librerie dinamiche e richiamare le funzioni da esse esportate.
public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inizializza queste variabili con il percorso completo di FREngine.dll, il tuo Customer Project ID
        // e, se applicabile, il percorso del file token della licenza online e la relativa password
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Carica la libreria 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 i puntatori in delegati
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Chiama la funzione InitializeEngine 
            // passando il percorso del file di licenza online e la relativa password
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libera la libreria FREngine.dll
            engine = null;
            // Elimina tutti gli oggetti prima della chiamata a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funzioni di 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);
    // Funzioni di 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();
    // Variabili private
    private FREngine.IEngine engine = null;
    // Handle di FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Caricamento dell’oggetto Engine tramite COM nel processo corrente

L’Engine viene caricato come server in-process nello stesso processo in cui è in esecuzione l’applicazione. L’oggetto Engine viene caricato mediante l’oggetto InprocLoader, che implementa l’interfaccia IEngineLoader.

Vantaggi

Limitazioni

  • Tutti gli oggetti di ABBYY FineReader Engine sono completamente thread-safe e possono essere creati e utilizzati in thread diversi.
  • Quando si opera dal Main STA apartment, le prestazioni sono uguali a quelle ottenute con le interfacce naked. Quando si accede da thread diversi, può verificarsi un overhead di marshalling, ma nella maggior parte degli scenari è trascurabile.
  • Per installare l’applicazione finale sul computer dell’utente finale, è necessario registrare FREngine.dll.
IEngineLoader engineLoader = new FREngine.InprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false );
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Per registrare FREngine.dll durante l’installazione dell’applicazione sul computer di un utente finale, usa l’utilità regsvr32. Se utilizzi un sistema operativo a 64 bit, per impostazione predefinita verrà eseguita la versione a 64 bit di regsvr32. Usa la seguente riga di comando:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"

Caricamento dell’oggetto Engine tramite COM in un processo separato

L’Engine viene caricato come server out-of-process in un processo separato. L’oggetto Engine viene caricato tramite l’oggetto OutprocLoader, che implementa l’interfaccia IEngineLoader.

Vantaggi

Limitazioni

  • Tutti gli oggetti di ABBYY FineReader Engine sono completamente thread-safe. Ogni istanza dell’Engine viene eseguita in un processo separato, in parallelo alle altre.
  • È possibile organizzare un pool di processori per sfruttare appieno la potenza della CPU del computer.
  • È presente un lieve overhead di marshalling.
  • La registrazione di FREngine.dll è necessaria durante l’installazione dell’applicazione finale nel computer dell’utente finale.
  • Quando si lavora con account con permessi limitati, è necessario concedere i permessi richiesti.
  • È impossibile accedere all’immagine di una pagina come HBITMAP.
  • Non può essere utilizzato con Visual Components, poiché non funzionano con processi multipli.
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false);
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Questo metodo di caricamento dell’oggetto Engine viene utilizzato, in particolare, nell’esempio di codice EnginesPool, che fornisce una soluzione riutilizzabile per le applicazioni multithread.
  • I permessi degli account possono essere configurati tramite l’utilità DCOM Config (digitando DCOMCNFG nella riga di comando oppure selezionando Control Panel > Administrative Tools > Component Services). Nell’albero della console, individuare la cartella Component Services > Computers > My Computer > DCOM Config, fare clic con il pulsante destro del mouse su ABBYY FineReader Engine 12.5 Loader (Local Server), quindi scegliere Properties. Si aprirà una finestra di dialogo. Fare clic sulla scheda Security. In Launch Permissions, fare clic su Customize, quindi su Edit per specificare gli account che possono avviare l’applicazione.
Si noti che in un sistema operativo a 64 bit l’applicazione DCOM registrata è disponibile nella console MMC a 32 bit, che può essere eseguita usando la seguente riga di comando:
"mmc comexp.msc /32"
  • Per registrare FREngine.dll durante l’installazione dell’applicazione su un computer dell’utente finale, utilizzare l’utilità regsvr32. Se si usa un sistema operativo a 64 bit, per impostazione predefinita verrà eseguita la versione a 64 bit di regsvr32. Utilizzare la seguente riga di comando:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Ti consigliamo di utilizzare una licenza di rete sia per eseguire il debug della tua applicazione server sia per mandarla in esecuzione.
Inoltre, puoi gestire la priorità di un processo host e controllare se è in esecuzione utilizzando l’interfaccia IHostProcessControl.

Tabella di confronto

La tabella seguente riassume le caratteristiche dei tre metodi di caricamento:
CaratteristicheInterfacce nakedServer in-processServer out-of-process
Funziona senza proxy (nessun overhead di marshalling)Con limitazioniNo
Funziona in applicazioni multithreadCon limitazioni
È possibile eseguire processi in parallelo (per soluzioni server)NoNo
Non è richiesta la registrazione di FREngine.dllNoNo
Non richiede la configurazione delle autorizzazioni di esecuzioneNo
Gli oggetti possono essere creati con l’operatore new. Funziona negli script.No
Possibilità di accedere all’immagine di una pagina come HBITMAPNo
Funziona in un processo separato (tolleranza ai guasti, riciclo)NoNo
Può essere usato con Visual ComponentsNo

Vedi anche

Utilizzo di ABBYY FineReader Engine in applicazioni server multithread