此函式用於取得 IEngine 介面的指標。它會將 Customer Project ID 編號作為輸入參數;此編號是您專案所使用的所有 Developer 與 Runtime 授權共用的英數字 string。
對 Linux 和 Windows 使用者而言,如有需要,此函式可讓您輕鬆存取線上授權管理,並可在初始化期間指定一些額外參數。
HRESULT __stdcall InitializeEngine (
BSTR CustomerProjectID ,
BSTR LicensePath ,
BSTR LicensePassword ,
BSTR FREngineDataFolder ,
BSTR FREngineTempFolder ,
VARIANT_BOOL IsSharedCPUCoresMode ,
IEngine** Engine
);
int InitializeEngine (
string CustomerProjectID ,
string LicensePath ,
string LicensePassword ,
string FREngineDataFolder ,
string FREngineTempFolder ,
bool IsSharedCPUCoresMode ,
ref IEngine Engine
);
Private Declare Function InitializeEngine Lib "FREngine.dll" ( _
CustomerProjectID As String , _
LicensePath As String , _
LicensePassword As String , _
FREngineDataFolder As String , _
FREngineTempFolder As String , _
IsSharedCPUCoresMode As Boolean , _
ByRef Engine As FREngine . IEngine ) _
As Integer
CustomerProjectID
[in] 包含 Customer Project ID 的 string。
在程式庫初始化期間,系統會在所有可用授權的清單中搜尋與此 Customer Project ID 對應的 Developer 或 Runtime License。若找不到對應的授權,則會發生最後一個已檢查授權的錯誤。不過,您也可以為此參數傳遞 0,並在呼叫任何其他程式庫方法之前,先呼叫 IEngine::SetCurrentLicense 方法來選取授權。
LicensePath
[in] 線上授權檔案的完整檔名。若您未使用線上授權,請改為傳遞空的 string "" 或 Null pointer。應傳遞空的 string "" 或 Null pointer。
對於 macOS 使用者:此參數保留供未來使用。
LicensePassword
[in] 線上授權密碼。若您未使用線上授權,請改為傳遞空的 string "" 或 Null pointer。
對於 macOS 使用者:此參數保留供未來使用。
FREngineDataFolder
[in] 包含 ABBYY FineReader Engine 應儲存使用者特定資料之資料夾的路徑。
依預設,若為自動安裝:
%ProgramData%\ABBYY\SDK\12\FineReader Engine for auxiliary engine data
此外,對於 Linux 和 Windows:
%ProgramData%\ABBYY\SDK\12\Licenses for license data
如果您設定 FREngineDataFolder 值,所有輔助資訊都會寫入新的資料夾。
例如,如果您的應用程式介面 language 設定必須與其他使用 FineReader Engine 的應用程式不同,您可能需要變更預設值。變更預設值後,請確認您對新的資料夾具有完整控制權限。
FREngineTempFolder
[in] 包含 ABBYY FineReader Engine 暫存檔案資料夾的路徑。依預設,為 %TEMP%\ABBYY FineReader Engine 12 資料夾。
IsSharedCPUCoresMode
[in] 指定 CPU cores 是否應以共用模式使用。CPU cores 的使用有兩種模式:獨立與共用。在獨立模式下,ABBYY FineReader Engine 使用的處理序數量不會超過授權允許的數量。在共用模式下,可以執行任意數量的處理序,但所有這些處理序都只會使用 IMultiProcessingParams::SharedCPUCoresMask property 所指定的 CPU cores。
此參數會在 ABBYY FineReader Engine for Windows 中被忽略。
Engine
[out, retval] 指向 IEngine* pointer 變數的指標,用於接收結果 Engine 物件的 interface pointer。
此函數可能會回傳 ABBYY FineReader Engine 函數的標準回傳值 。
在使用 ABBYY FineReader Engine 的單一應用程式執行個體中,使用此函式只能建立一個 Engine 物件。若重複嘗試建立 Engine 物件,會傳回相同的物件。
建立 Engine 物件可能需要一些明顯的時間。在初始化期間,Engine 會載入下列主要程式庫,以及大量其他動態程式庫:
Linux:libFREngine.so
macOS:libFREngine.dylib
Windows:FREngine.dll
使用網路授權時,Linux 和 Windows 的初始化也可能因與授權伺服器通訊而耗時較久。請確認網路連線符合所需效能;建議頻寬至少為 100 Kb/s,以確保網路授權能可靠運作。
您可以在多處理器系統上建立並執行 Engine 物件,但每個處理序中只能有一個 Engine 物件。在同一個處理序內第二次呼叫 InitializeEngine 時,將會傳回現有物件的參考。因此,您應透過呼叫 InitializeEngine 函式,為每個處理序建立個別的 Engine 物件。
對於涉及多處理器系統的 ABBYY FineReader Engine for Windows 實作,您可能會覺得載入 Engine 物件的其他方法 很實用。
請勿在其他動態程式庫的進入點,以及在動態程式庫中實作之靜態與全域物件的建構函式和解構函式中初始化或解除初始化 ABBYY FineReader Engine,因為這些函式會在動態程式庫進入點呼叫。
使用者應在其他位置初始化與解除初始化 ABBYY FineReader Engine。例如,在可執行模組的 main 或 WinMain 函式中。
:在 Windows 中,此限制是因為 Win32 的 LoadLibrary 與 FreeLibrary 函式不是可重入的。
在初始化期間,ABBYY FineReader Engine 會將 LC_CTYPE 設定重設為作業系統預設值。如果您的應用程式依賴與地區設定相關的服務 (尤其是 Windows 中的 msvcrt.dll) ,則應將此情況納入考量。
使用 .NET 的 Windows 開發人員必須確保在應用程式主函式上將 [STAThread] (單一執行緒 Apartment 模型) 指定為屬性;否則可能會發生錯誤:
[STAThread]
public static void Main()
{
...
}
您應將有效的 Customer Project ID 號碼作為輸入參數傳入。不過,您也可以在任何處理方法執行前,呼叫 Engine 物件 的 SetCurrentLicense 方法,選擇要用於處理的授權。使用 GetAvailableLicenses 方法,可檢視您可使用的已啟用授權清單;並使用 Engine 物件 的 CurrentLicense 屬性,確認目前已選取的是哪個授權。
// 使用 FREngine.dll 的路徑、您的 FineReader Engine 客戶專案 ID,
// 以及(如果適用)線上授權權杖的路徑和線上授權密碼來初始化這些變數
wchar_t * FreDllPath;
wchar_t * CustomerProjectId;
wchar_t * LicensePath; // 如果您不使用線上授權,請將這些變數指派為空字串
wchar_t * LicensePassword;
// FREngine.dll 的 HANDLE
static HMODULE libraryHandle = 0 ;
// 全域 FineReader Engine 物件。
FREngine ::IEnginePtr Engine;
void LoadFREngine ()
{
if ( Engine != 0 ) {
// 已載入
return ;
}
// 第一步:載入 FREngine.dll
if ( libraryHandle == 0 ) {
libraryHandle = LoadLibraryEx ( FreDllPath, 0 , LOAD_WITH_ALTERED_SEARCH_PATH );
if ( libraryHandle == 0 ) {
throw L"載入 ABBYY FineReader Engine 時發生錯誤" ;
}
}
// 第二步:取得 Engine 物件
typedef HRESULT ( STDAPICALLTYPE * InitializeEngineFunc )( BSTR, BSTR, BSTR, BSTR,
BSTR, VARIANT_BOOL, FREngine ::IEngine ** );
InitializeEngineFunc pInitializeEngine =
( InitializeEngineFunc ) GetProcAddress ( libraryHandle, "InitializeEngine" );
if ( pInitializeEngine == 0 || pInitializeEngine ( CustomerProjectId, LicensePath,
LicensePassword, L"" , L"" , VARIANT_FALSE, & Engine ) != S_OK ) {
UnloadFREngine ();
throw L"載入 ABBYY FineReader Engine 時發生錯誤" ;
}
}
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 ;
}
此函式用於所有程式碼範例 ,但 EnginesPool (Win) 除外。
授權管理
模組
DeinitializeEngine
Engine 物件 的不同載入方式 (Win)