メインコンテンツへスキップ
このトピックは Windows 版の FRE に適用されます。
ABBYY FineReader Engine 12 で Engine オブジェクトをロードする方法は 3 つあります。これらのロード方法にはそれぞれ特有の違いがあり、状況に応じたオブジェクトの使い方に影響します。最初の 2 つの方法は、複数のリクエストを同時に処理することを想定していない対話型アプリケーションでの使用に最も適しています。3 つ目の方法は、サーバーソリューションに最も適しています。

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 へのハンドル
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

COM を使用して現在のプロセスに Engine object をロードする

Engine は、アプリケーションが実行されているのと同じプロセス内に、インプロセス サーバーとしてロードされます。Engine object は、IEngineLoader インターフェイスを実装する InprocLoader object を使用してロードされます。

利点

制限事項

  • すべての ABBYY FineReader Engine object は完全にスレッドセーフであり、異なるスレッドで作成して使用できます。
  • メインの 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 オブジェクトは、IEngineLoader インターフェイスを実装する OutprocLoader オブジェクトによってロードされます。

利点

制限事項

  • すべての 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) を右クリックして [Properties] をクリックします。ダイアログが開きます。[Security] タブをクリックします。[Launch Permissions] で [Customize] をクリックし、次に [Edit] をクリックして、アプリケーションを起動できるアカウントを指定します。
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 インターフェイスを使用して、ホストプロセスの優先度を管理し、稼働状態を制御できます。

比較表

以下の表は、3 つのロード方法の特性をまとめたものです。
特性生のインターフェイスインプロセスサーバーアウトプロセスサーバー
プロキシなしで動作する (マーシャリング オーバーヘッドなし)はい制限がありますいいえ
マルチスレッド アプリケーションで動作する制限がありますはいはい
プロセスを並列実行できる (サーバー ソリューション向け)いいえいいえはい
FREngine.dll の登録が不要はいいいえいいえ
実行権限を設定する必要がないはいはいいいえ
new 演算子を使用してオブジェクトを作成できる。スクリプトからも使用できる。いいえはいはい
ページ画像に HBITMAP としてアクセスできるはいはいいいえ
別プロセスで動作する (フェールセーフ、リサイクル)いいえいいえはい
Visual Components と併用できるはいはいいいえ

関連項目

ABBYY FineReader Engine をマルチスレッド サーバー アプリケーションで使用する