运行时动态加载库
-
在一个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_,从而更新此列表。 -
@Micro 我有个朋友写过相关的博文,感兴趣可以看看
https://zmeng.tech/2020/10/DynamicLibraries/