自动加载模块是CppMicroServices库的一个功能,用于管理加载模块,这些模块由于缺少链接时间依赖关系而通常不会在运行时被加载。
1 问题来源
- 假设你有一个模块A,它提供了一个加载文件的接口,另一个模块B注册了一个服务,实现了接口类型为png的文件。你的可执行文件E使用A的接口来查询服务注册表以获取可用的服务。由于链接时间依赖性,这导致了以下依赖关系图:(官网图片缺失)
- 当可执行文件E启动时,你的操作系统的动态链接程序将加载模块A以满足E的依赖关系,但模块B将不会被加载。因此,可执行文件将无法使用模块B的任何服务。
2 解决方案
- 上面的问题可通过在CppMicroServices库中自动从可配置的文件系统位置列表中加载模块来解决。
- 对于每个正在加载的模块,采取以下步骤:
- 如果模块提供激活器activator,则调用ModuleActivator :: Load()方法;
- 如果启用了自动加载,并且模块声明了非空的自动加载目录,则会处理从ModuleSettings :: GetAutoLoadPaths()返回的自动加载路径;
- 对于每个自动加载路径,显式加载具有当前加载的模块的自动加载目录的路径中的所有模块。
- 有关自动加载路径的详细信息,请参阅ModuleSettings类。 模块的自动加载目录默认为模块的库名称,但可以使用manifest.json文件进行自定义(请参Module Properties)。 对于可执行文件,自动加载目录默认为特殊值main。 这允许第三方模块在应用程序启动时自动加载,而不必引用特殊的自动加载目录。
- 示例:
- 如果上面的例子中的模块A包含初始化代码:
US_INITIALIZE_MODULE("Module A", "A")
- 并且模块的库位于:
/myproject/libA.so
- 所有的库都位于:
/myproject/A/
- 若上述示例中的模块B位于以下位置,则将自动加载(除非自动加载路径已被修改):
/myproject/A/libB.so
- 它将在可执行文件E启动时被加载,然后在可执行文件查询服务注册表之前注册它的服务。
注意:如果你需要在应用程序启动时添加其他自动加载搜索路径,需在你的可执行文件中提供一个ModuleActivator实例,并在可执行文件的ModuleActivator :: Load()方法中调用ModuleSettings :: AddAutoLoadPath()。 如果任何提供的自动加载搜索路径的主子目录内有模块,那么这些模块将在执行main()函数之前自动加载。
3 环境变量
以下环境变量将会影响CppMicroServices库的运行时行为:
- US_DISABLE_AUTOLOADING:如果设置,模块的自动加载将被禁用;
- US_AUTOLOAD_PATHS:需要自动加载的模块的路径列表。