在一个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_,从而更新此列表。