此函数用于获取指向 IEngine 接口的指针。它将 Customer Project ID 编号作为输入参数;该编号是一个字母数字字符串,为您的项目所使用的所有开发者和运行时许可证共用。
对于 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 对应的开发者许可证或运行时许可证。如果未找到对应的许可证,则会针对最后检查的许可证引发错误。不过,您也可以为此参数传递 0,并在调用任何其他库方法之前,通过调用 IEngine::SetCurrentLicense 方法稍后选择许可证。
LicensePath
[in] Online License 文件的完整文件名。如果您不使用 Online License,请传递空 string "" 或 Null 指针。应传递空 string "" 或 Null 指针。
对于 macOS 用户:此参数保留供将来使用。
LicensePassword
[in] Online License 密码。如果您不使用 Online License,请传递空 string "" 或 Null 指针。
对于 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 值,所有辅助信息都将写入新的数据文件夹。
例如,如果您的应用程序界面语言设置必须不同于其他使用 FineReader Engine 的应用程序,您可能需要更改默认值。更改默认值后,请确保您对新的数据文件夹具有完全控制权限。
FREngineTempFolder
[in] 包含 ABBYY FineReader Engine 临时文件夹的路径。默认情况下,该文件夹为 %TEMP%\ABBYY FineReader Engine 12。
IsSharedCPUCoresMode
[in] 指定是否以共享模式使用 CPU 核心。CPU 核心的使用有两种模式:独立和共享。在独立模式下,ABBYY FineReader Engine 使用的进程数不会超过许可证允许的数量。在共享模式下,可以运行任意数量的进程,但所有这些进程都只会使用 IMultiProcessingParams::SharedCPUCoresMask 属性指定的 CPU 核心。
在 ABBYY FineReader Engine for Windows 中,此参数会被忽略。
Engine
[out, retval] 指向 IEngine* 指针变量的指针,该变量接收结果 Engine 对象的 interface pointer。
该函数可能返回 ABBYY FineReader Engine 函数的标准返回值 。
在使用 ABBYY FineReader 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] (单线程单元模型) 指定为特性;否则可能会发生错误:
[STAThread]
public static void Main()
{
...
}
您应将有效的 Customer Project ID 编号作为输入参数传入。不过,您也可以在调用任何处理方法之前,先调用 Engine 对象的 SetCurrentLicense 方法,以选择要用于处理的许可证。使用 GetAvailableLicenses 方法可查看可用的已激活许可证列表,并可通过 Engine 对象的 CurrentLicense 属性检查当前选用的是哪个许可证。
// 使用 FREngine.dll 的路径、您的 FineReader Engine 客户项目 ID,
// 以及(如适用)Online License 令牌路径和 Online License 密码初始化这些变量
wchar_t * FreDllPath;
wchar_t * CustomerProjectId;
wchar_t * LicensePath; // 如果不使用 Online License,请将这些变量赋为空字符串
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"Error while loading 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"Error while loading ABBYY FineReader Engine" ;
}
}
public class EngineLoader : IDisposable
{
public EngineLoader ()
{
// 使用 FREngine.dll 的完整路径、您的 Customer Project ID,
// 以及(如适用)您的 Online License 令牌文件路径和 Online License 密码初始化这些变量
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 函数
// 传入 Online License 令牌文件路径和 Online License 密码
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 ;
}
除 EnginesPool (Win) 外,所有代码示例 都会使用此函数。
许可管理
模块
DeinitializeEngine
加载 Engine 对象的不同方式 (Win)