运行时动态加载库
-
在一个solver或者util运行时,会自动加载链接器链接到它身上的库,但想在运行时动态地通过字典文件灵活加载动态库该怎么办呢?可以通过这样的操作:
const_cast<Time&>(io.time()).libs().open ( dict, "dynamicFvMeshLibs", IOobjectConstructorTablePtr_ ); 操作会加载dict中dynamicFvMeshLibs声明的库,并通过与IOobjectConstructorTablePtr_ 这个列表对比是否为已经加载过的类。跳转到libs()函数返回的dlLibraryTable对象的open函数
template<class TablePtr> bool Foam::dlLibraryTable::open ( const dictionary& dict, const word& libsEntry, const TablePtr& tablePtr ) { fileNameList libNames; dict.readIfPresent(libsEntry, libNames); label nOpen = 0; for (const fileName& libName : libNames) { const label nEntries = (tablePtr ? tablePtr->size() : 0); if (dlLibraryTable::open(libName)) { ++nOpen; if (debug && (!tablePtr || tablePtr->size() <= nEntries)) { WarningInFunction << "library " << libName << " did not introduce any new entries" << nl << endl; } } ... 注意传入的tablePtr是const& ,意味着在函数体内不能修改。
dict.readIfPresent(libsEntry, libNames);通过libsEntry读取一系列动态库名,并在for循环中遍历,并通过open函数真正加载动态库。需要注意的是nEntries在open函数前等于tablePtr->size(),而在之后又与tablePtr->size() <= nEntries进行对比,只能说明tablePtr在open中被修改了,但tablePtr的是const的呀!很好理解,传入的IOobjectConstructorTablePtr_是全局静态变量,在函数体外修改是没得关系的。具体就是在open动态库的时候addToRunTimeSelectionTable(dynamicFvMesh, dynamicRefineFvMesh, IOobject);这一句被调用,它会把自己的typeName插入到IOobjectConstructorTablePtr_,从而更新此列表。 -
真厉害!之前一直没有见过深入讲解“运行时动态加载库”的文章,我按照你说的好好看一下。
-
对了老师,这种运行时加载动态库的操作 是不是 这里的动态库不能是任意的动态库,而必须是继承已有基类的子类编写而成的动态库。就比如,基类是solver,子类是一系列具体迭代方法;基类是边界条件,子类是一系列具体边条。总是这些子类形成的动态库所提供的方法都是在字典文件中以关键字可选项的形式出现的。我的问题是:如果我们用户自定义一种完全脱离OF中基类的独立的动态库,那么此时要想调用该库,是不是必须编译上层应用再链接该库,而不是像您这篇帖子中所说的通过在congtrolDict中添加libs的形式来动态调用该库呢?谢谢!
-
@Micro 我有个朋友写过相关的博文,感兴趣可以看看
https://zmeng.tech/2020/10/DynamicLibraries/ -
@Micro 我有个朋友写过相关的博文,感兴趣可以看看
https://zmeng.tech/2020/10/DynamicLibraries/
6/8