Passer au contenu principal
Cette rubrique s’applique à FRE pour Windows.
Il existe trois façons de charger l’objet Engine dans ABBYY FineReader Engine 12. Chacune de ces méthodes de chargement présente des spécificités qui influent sur l’utilisation de l’objet selon le contexte. Les deux premières conviennent davantage aux applications interactives qui ne sont pas destinées au traitement simultané de plusieurs requêtes. La troisième est plus adaptée aux solutions serveur.

Chargement manuel de FREngine.dll et utilisation d’interfaces « nues »

Il s’agit de la méthode standard pour charger l’objet Engine. Pour obtenir une référence à l’objet Engine, appelez la fonction InitializeEngine.

Avantages

Limites

  • Garantit des performances maximales.
  • Ne nécessite pas l’enregistrement de FREngine.dll.
public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Initialisez ces variables avec le chemin complet vers FREngine.dll, votre Customer Project ID
        // et, le cas échéant, le chemin vers votre fichier de jeton de licence en ligne ainsi que le mot de passe de la licence en ligne
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Charger la bibliothèque 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");
            }
            // Convertir les pointeurs en délégués
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Appeler la fonction InitializeEngine
            // en passant le chemin vers le fichier de licence en ligne et le mot de passe de la licence en ligne
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libérer la bibliothèque FREngine.dll
            engine = null;
            // Supprimer tous les objets avant l'appel à FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Fonctions 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);
    // Fonctions 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 privées
    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;
}

Chargement de l’objet Engine au moyen de COM dans le processus en cours

L’objet Engine est chargé comme serveur in-process dans le même processus que celui dans lequel l’application s’exécute. L’objet Engine est chargé à l’aide de l’objet InprocLoader, qui implémente l’interface IEngineLoader.

Avantages

Limites

  • Tous les objets ABBYY FineReader Engine sont entièrement thread-safe et peuvent être créés et utilisés dans différents threads.
  • Lorsqu’il est utilisé depuis l’appartement STA principal, le niveau de performance est identique à celui obtenu avec les interfaces nues. En cas d’accès depuis différents threads, une surcharge liée au marshaling peut se produire, mais elle est négligeable dans la plupart des scénarios.
  • L’enregistrement de FREngine.dll est requis lors de l’installation de l’application finale sur l’ordinateur de l’utilisateur final.
IEngineLoader engineLoader = new FREngine.InprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false );
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Pour enregistrer FREngine.dll lors de l’installation de votre application sur l’ordinateur d’un utilisateur final, utilisez l’utilitaire regsvr32. Si vous êtes sur un système d’exploitation 64 bits, la version 64 bits de regsvr32 s’exécute par défaut. Utilisez la ligne de commande suivante :
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"

Chargement de l’objet Engine via COM dans un processus séparé

L’Engine est chargé en tant que serveur hors processus dans un processus séparé. L’objet Engine est chargé au moyen de l’objet OutprocLoader, qui implémente l’interface IEngineLoader.

Avantages

Limitations

  • Tous les objets ABBYY FineReader Engine sont entièrement thread-safe. Chaque instance de l’Engine s’exécute dans un processus séparé, en parallèle des autres.
  • Un pool de processeurs peut être organisé pour exploiter pleinement la puissance CPU de l’ordinateur.
  • Il existe une légère surcharge de marshalling.
  • L’enregistrement de FREngine.dll est requis lors de l’installation de l’application finale sur l’ordinateur d’un utilisateur final.
  • En cas d’utilisation sous des comptes avec des autorisations limitées, les autorisations nécessaires doivent être accordées.
  • Il est impossible d’accéder à une image de page en tant que HBITMAP.
  • Ne peut pas être utilisé avec les composants visuels, car ceux-ci ne fonctionnent pas avec plusieurs processus.
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false);
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Cette méthode de chargement de l’objet Engine est utilisée, notamment, dans l’exemple de code EnginesPool, qui fournit une solution réutilisable pour les applications multithread.
  • Les autorisations de compte peuvent être configurées à l’aide de l’utilitaire DCOM Config (saisissez DCOMCNFG dans la ligne de commande, ou sélectionnez Panneau de configuration > Outils d’administration > Services de composants). Dans l’arborescence de la console, localisez le dossier Services de composants > Ordinateurs > Poste de travail > Configuration DCOM, faites un clic droit sur ABBYY FineReader Engine 12.5 Loader (Local Server), puis cliquez sur Propriétés. Une boîte de dialogue s’ouvre. Cliquez sur l’onglet Sécurité. Sous Autorisations de lancement, cliquez sur Personnaliser, puis sur Modifier pour spécifier les comptes autorisés à lancer l’application.
Notez que sur un système d’exploitation 64 bits, l’application DCOM enregistrée est disponible dans la console MMC 32 bits, qui peut être lancée à l’aide de la ligne de commande suivante :
"mmc comexp.msc /32"
  • Pour enregistrer FREngine.dll lors de l’installation de votre application sur l’ordinateur d’un utilisateur final, utilisez l’utilitaire regsvr32. Si vous utilisez un système d’exploitation 64 bits, la version 64 bits de regsvr32 s’exécute par défaut. Utilisez la ligne de commande suivante :
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Nous vous recommandons d’utiliser une licence réseau aussi bien pour déboguer votre application serveur que pour l’exécuter.
De plus, vous pouvez gérer la priorité d’un processus hôte et vérifier s’il est en cours d’exécution à l’aide de l’interface IHostProcessControl.

Tableau comparatif

Le tableau ci-dessous résume les caractéristiques des trois méthodes de chargement :
CaractéristiquesInterfaces nuesServeur in-processServeur hors processus
Fonctionne sans proxy (sans surcharge de marshalling)OuiCertaines limitations s’appliquentNon
Fonctionne dans des applications multithreadCertaines limitations s’appliquentOuiOui
L’exécution parallèle de plusieurs processus est possible (pour les solutions serveur)NonNonOui
L’enregistrement de FREngine.dll n’est pas requisOuiNonNon
Aucune autorisation d’exécution n’est nécessaireOuiOuiNon
Les objets peuvent être créés à l’aide de l’opérateur new. Utilisable depuis des scripts.NonOuiOui
Possibilité d’accéder à l’image d’une page sous forme de HBITMAPOuiOuiNon
Fonctionne dans un processus distinct (tolérance aux pannes, recyclage)NonNonOui
Peut être utilisé avec les composants visuelsOuiOuiNon

Voir aussi

Utilisation d’ABBYY FineReader Engine dans des applications serveur multithreadées