跳轉到主要內容
本主題適用於 Windows 版的 FRE。
在 ABBYY FineReader Engine 12 中,有三種方式可以載入 Engine 物件。每種載入方法都有其獨特性,會影響物件在不同情境下的使用。前兩種方法最適合用於不需同時處理多個請求的互動式應用程式。第三種方法最適合用於伺服器解決方案。

手動載入 FREngine.dll 並使用「裸介面」

這是載入 Engine 物件的標準方法。若要取得 Engine 物件的參考,請呼叫 InitializeEngine 函式。

優點

限制

  • 可提供最佳效能。
  • 不需要註冊 FREngine.dll。
public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // 請使用 FREngine.dll 的完整路徑、您的 Customer Project ID,
        // 以及(如適用)線上授權權杖檔案的路徑和線上授權密碼來初始化這些變數
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // 載入 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");
            }
            // 將指標轉換成委派
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // 呼叫 InitializeEngine 函式 
            // 傳入線上授權檔案路徑和線上授權密碼
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // 釋放 FREngine.dll 程式庫
            engine = null;
            // 在呼叫 FreeLibrary 前釋放所有物件
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // 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);
    // 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 FREngine.IEngine engine = null;
    // FREngine.dll 的 Handle
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

透過 COM 將 Engine 物件載入目前處理序

Engine 以處理序內伺服器的形式載入到應用程式執行的相同處理序中。Engine 物件是使用實作 IEngineLoader 介面的 InprocLoader 物件來載入。

優點

限制

  • 所有 ABBYY FineReader Engine 物件完全執行緒安全,並可在不同執行緒中建立和使用。
  • 從主 STA 單元工作時,效能與直接使用介面相同。從不同執行緒存取時,可能會產生封送處理的額外負荷,但在大多數情境中可忽略不計。
  • 在終端使用者電腦上安裝最終應用程式時,需要註冊 FREngine.dll。
IEngineLoader engineLoader = new FREngine.InprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false );
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
要在終端使用者電腦上安裝應用程式時註冊 FREngine.dll,請使用 regsvr32 公用程式。如果您在 64 位元作業系統上,預設會執行 64 位元版本的 regsvr32。請使用下列命令列:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"

透過 COM 將 Engine 物件載入至個別處理序

Engine 會以處理序外伺服器的形式載入到個別處理序中。Engine 物件會透過 OutprocLoader 物件載入,而該物件實作了 IEngineLoader 介面。

優點

限制

  • 所有 ABBYY FineReader Engine 物件都完全具備執行緒安全性。每個 Engine 執行個體都會在與其他執行個體平行的個別處理序中執行。
  • 可建立處理序集區,以充分利用電腦的 CPU 效能。
  • 會有少量封送處理額外負擔。
  • 在終端使用者的電腦上安裝最終應用程式時,必須註冊 FREngine.dll。
  • 使用權限受限的帳戶時,必須授與必要的權限。
  • 無法以 HBITMAP 的形式存取頁面影像。
  • 無法與 Visual Components 搭配使用,因為它們不支援多處理序。
IEngineLoader engineLoader = new FREngine.OutprocLoader();
IEngine engine = engineLoader.InitializeEngine( customerProjectId, licensePath, licensePassword, "", "", false);
try {
 ...
} finally {
 engineLoader.ExplicitlyUnload();
}
這種載入 Engine 物件的方式尤其用於 EnginesPool 程式碼範例中,該範例為多執行緒應用程式提供可重複使用的解決方案。
  • 可使用 DCOM Config 公用程式設定帳戶權限 (可在命令列輸入 DCOMCNFG,或選取「控制台 > 系統管理工具 > 元件服務」) 。在主控台樹狀目錄中,找到「元件服務 > 電腦 > 我的電腦 > DCOM Config」資料夾,然後以滑鼠右鍵按一下 ABBYY FineReader Engine 12.5 Loader (Local Server),再按一下「內容」。隨即會開啟一個對話方塊。按一下「安全性」索引標籤。在「啟動權限」下,按一下「自訂」,然後按一下「編輯」,以指定可啟動應用程式的帳戶。
請注意,在 64 位元作業系統上,已註冊的 DCOM 應用程式可在 32 位元 MMC 主控台中使用,並可透過下列命令列執行:
"mmc comexp.msc /32"
  • 若要在使用者電腦上安裝應用程式時註冊 FREngine.dll,請使用 regsvr32 公用程式。若您使用的是 64 位元作業系統,系統預設會執行 64 位元版本的 regsvr32。請使用下列命令列:
regsvr32 /s /n /i:"<path to the Inc folder>" "<path to FREngine.dll>"
  • 我們建議您在偵錯及執行伺服器應用程式時,都使用 Network license。
此外,您可以透過 IHostProcessControl 介面管理主機處理序的優先順序,並控制其是否仍在執行。

比較表

下表概述三種載入方法的特性:
特性裸介面處理序內伺服器處理序外伺服器
可在無 Proxy 的情況下運作 (無封送處理額外負擔)有限制
可在多執行緒應用程式中運作有限制
可平行執行多個處理序 (適用於伺服器解決方案)
無需註冊 FREngine.dll
無需設定執行權限
可使用 new 運算子建立物件,並可從指令碼使用。
可將頁面影像作為 HBITMAP 存取
可在獨立處理序中運作 (具容錯能力、可回收)
可與 Visual Components 搭配使用

另請參閱

在多執行緒伺服器應用程式中使用 ABBYY FineReader Engine