Zum Hauptinhalt springen
Dieses Thema gilt für FRE unter Windows.
Es gibt drei Möglichkeiten, das Engine-Objekt in ABBYY FineReader Engine 12 zu laden. Jede dieser Methoden hat ihre eigenen Besonderheiten, die sich je nach Einsatzszenario auf die Verwendung des Objekts auswirken. Die ersten beiden Methoden eignen sich am besten für interaktive Anwendungen, die nicht für die gleichzeitige Verarbeitung mehrerer Anfragen ausgelegt sind. Die dritte Methode eignet sich am besten für Serverlösungen.

FREngine.dll manuell laden und mit „nackten“ Schnittstellen arbeiten

Dies ist die Standardmethode zum Laden des Engine-Objekts. Um eine Referenz auf das Engine-Objekt zu erhalten, rufen Sie die Funktion InitializeEngine auf.

Vorteile

Einschränkungen

  • Bietet maximale Leistung.
  • Erfordert keine Registrierung von FREngine.dll.
public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Initialisieren Sie diese Variablen mit dem vollständigen Pfad zu FREngine.dll, Ihrer Customer Project ID
        // und gegebenenfalls dem Pfad zu Ihrer Online-Lizenz-Token-Datei sowie dem Kennwort der Online-Lizenz
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Die Bibliothek FREngine.dll laden
        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");
            }
            // Zeiger in Delegaten umwandeln
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Die Funktion InitializeEngine aufrufen 
            // und dabei den Pfad zur Online-Lizenz-Datei und das Kennwort der Online-Lizenz übergeben
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Die Bibliothek FREngine.dll freigeben
            engine = null;
            // Alle Objekte vor dem Aufruf von FreeLibrary löschen
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funktionen aus 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);
    // Funktionen aus 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();
    // Private Variablen
    private FREngine.IEngine engine = null;
    // Handle für FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Laden des Engine-Objekts per COM in den aktuellen Prozess

Die Engine wird als In-Process-Server in denselben Prozess geladen, in dem die Anwendung ausgeführt wird. Das Engine-Objekt wird über das Objekt InprocLoader geladen, das die Schnittstelle IEngineLoader implementiert.

Vorteile

Einschränkungen

  • Alle Objekte von ABBYY FineReader Engine sind vollständig thread-sicher und können in verschiedenen Threads erstellt und verwendet werden.
  • Bei der Arbeit aus dem Main-STA-Apartment entspricht die Leistung der Arbeit mit den nackten Schnittstellen. Beim Zugriff aus verschiedenen Threads kann Marshalling-Overhead auftreten, dieser ist in den meisten Szenarien jedoch vernachlässigbar.
  • Bei der Installation der fertigen Anwendung auf dem Computer eines Endbenutzers muss FREngine.dll registriert werden.
IEngineLoader engineLoader = new FREngine.InprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false );
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Um FREngine.dll bei der Installation Ihrer Anwendung auf dem Computer eines Endbenutzers zu registrieren, verwenden Sie das Dienstprogramm regsvr32. Wenn Sie ein 64-Bit-Betriebssystem verwenden, wird standardmäßig die 64-Bit-Version von regsvr32 ausgeführt. Verwenden Sie die folgende Befehlszeile:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"

Laden des Engine-Objekts mithilfe von COM in einen separaten Prozess

Die Engine wird als Out-of-Process-Server in einen separaten Prozess geladen. Das Engine-Objekt wird mithilfe des Objekts OutprocLoader geladen, das die Schnittstelle IEngineLoader implementiert.

Vorteile

Einschränkungen

  • Alle Objekte von ABBYY FineReader Engine sind vollständig threadsicher. Jede Instanz der Engine wird parallel zu den anderen in einem separaten Prozess ausgeführt.
  • Es kann ein Pool von Prozessoren eingerichtet werden, um die CPU-Leistung des Computers vollständig auszuschöpfen.
  • Es entsteht ein geringer Marshalling-Overhead.
  • Bei der Installation der fertigen Anwendung auf dem Computer eines Endbenutzers muss FREngine.dll registriert werden.
  • Bei der Arbeit unter Konten mit eingeschränkten Berechtigungen müssen die erforderlichen Berechtigungen erteilt werden.
  • Es ist nicht möglich, auf ein Seitenbild als HBITMAP zuzugreifen.
  • Kann nicht mit Visual Components verwendet werden, da diese nicht mit mehreren Prozessen funktionieren.
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false);
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
Diese Art, das Engine-Objekt zu laden, wird insbesondere im Codebeispiel EnginesPool verwendet, das eine wiederverwendbare Lösung für Multithreading-Anwendungen bietet.
  • Kontoberechtigungen können mit dem Dienstprogramm DCOM Config eingerichtet werden (geben Sie entweder DCOMCNFG in der Befehlszeile ein oder wählen Sie Control Panel > Administrative Tools > Component Services). Suchen Sie in der Konsolenstruktur den Ordner Component Services > Computers > My Computer > DCOM Config, klicken Sie mit der rechten Maustaste auf ABBYY FineReader Engine 12.5 Loader (Local Server), und klicken Sie auf Properties. Ein Dialogfeld wird geöffnet. Klicken Sie auf die Registerkarte Security. Klicken Sie unter Launch Permissions auf Customize und dann auf Edit, um die Konten anzugeben, die die Anwendung starten dürfen.
Beachten Sie, dass auf einem 64-Bit-Betriebssystem die registrierte DCOM-Anwendung in der 32-Bit-MMC-Konsole verfügbar ist, die mit der folgenden Befehlszeile ausgeführt werden kann:
"mmc comexp.msc /32"
  • Um FREngine.dll bei der Installation Ihrer Anwendung auf dem Computer des Endbenutzers zu registrieren, verwenden Sie das Tool regsvr32. Wenn Sie ein 64-Bit-Betriebssystem verwenden, wird standardmäßig die 64-Bit-Version von regsvr32 ausgeführt. Verwenden Sie die folgende Befehlszeile:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • Wir empfehlen, zum Debuggen und Ausführen Ihrer Serveranwendung eine Netzwerklizenz zu verwenden.
Außerdem können Sie über die Schnittstelle IHostProcessControl die Priorität eines Hostprozesses festlegen und steuern, ob er ausgeführt wird.

Vergleichstabelle

Die folgende Tabelle fasst die Merkmale der drei Lademethoden zusammen:
EigenschaftenNaked InterfacesIn-Process-ServerOut-of-Process-Server
Funktioniert ohne Proxy (kein Marshalling-Overhead)JaEs gibt EinschränkungenNein
Funktioniert in Anwendungen mit mehreren ThreadsEs gibt EinschränkungenJaJa
Parallele Prozesse sind möglich (für Serverlösungen)NeinNeinJa
Keine Registrierung von FREngine.dll erforderlichJaNeinNein
Es müssen keine Ausführungsberechtigungen konfiguriert werdenJaJaNein
Objekte können mit dem new-Operator erstellt werden. Funktioniert in Skripten.NeinJaJa
Möglichkeit, auf ein Seitenbild als HBITMAP zuzugreifenJaJaNein
Funktioniert in einem separaten Prozess (ausfallsicher, Recycling)NeinNeinJa
Kann mit Visual Components verwendet werdenJaJaNein

Siehe auch

Einsatz von ABBYY FineReader Engine in Multithread-Serveranwendungen