Проблема, с которой я сталкиваюсь, заключается в следующем:
Я генерирую общий объект под названием customkinetics.so из файла f90
Я использую этот объект в Cantera (код химии), написанном на C ++ с интерфейсом Python.
Объект вызывается в подпрограмме (CustomKinetics.cpp) следующим образом:
#include "cantera/kinetics/CustomKinetics.h"
#include <iostream>
#include <dlfcn.h>
using namespace std;
namespace Cantera
{
//Fortran External Routine
extern "C"{
void customkinetics_(doublereal* P, doublereal* T, doublereal* rho, const doublereal* m_y, doublereal* wdot);
}
CustomKinetics::CustomKinetics(thermo_t* th) : GasKinetics(th)
{
printf("WARNING: Using customized kinetics from f90 file.\n");
// Closing the library if it has already been opened
if (handle == NULL){
dlclose(handle);
}
handle = dlopen("customkinetics.so", RTLD_LAZY | RTLD_LOCAL);
// load symbol
ck = (ck_t) dlsym(handle, "customkinetics_");
}
void CustomKinetics::get_wdot_custom(doublereal* wdot)
{
doublereal P = thermo().pressure();
doublereal T = thermo().temperature();
doublereal rho = thermo().density();
const doublereal* m_y = thermo().massFractions();
// calculation
ck(&P,&T,&rho,&m_y[0],&wdot[0]);
}
}
Он работает нормально, пока я не перезаписываю файл .f90, который затем снова компилирую, перезаписывая .so, а затем, когда я вызываю его снова, я фактически вызываю первый объект.
Я знаю, что dlclose () не должен полностью удалять объект из памяти, но есть ли способ сделать это?
Фортран Makefile:
customkinetics.so: customkinetics.f90
gfortran -c customkinetics.f90 -g -fPIC -o customkinetics.o
gfortran -shared -o customkinetics.so customkinetics.o
Я думаю, что лучше понять, почему динамический разделяемый объект все еще является резидентным, а не пытаться принудительно выгрузить его. dlclose()
выгрузит динамический общий объект из памяти, если счетчик ссылок на этот объект упадет до нуля. Вы уверены, что количество dlopen()
а также dlclose()
звонки в вашем коде одинаковые?
Также возможно, что счетчик ссылок был неявно увеличен из-за других зависимостей. Можете ли вы подтвердить, что ничто другое не зависит от вашего общего объекта?
На связанной ноте вы передаете NULL
к dlclose()
позвоните в ваш конструктор. Вы намеревались проверить, handle
является не NULL
т.е.
// Closing the library if it has already been opened
if (handle != NULL){
dlclose(handle);
}
Других решений пока нет …