Я пытаюсь загрузить класс из динамического c библиотеки. Этот класс должен наследоваться от интерфейса с именем IDisplayModule
:
class IDisplayModule {
public:
virtual ~IDisplayModule() = default;
virtual const std::string &getName() const = 0;
};
Я создал класс DLLoader
, который используется для загрузки динамического c lib:
template <typename T>
class DLLoader {
private:
std::string _libraryPath;
void *_handle;
public:
DLLoader<T>(const std::string &libraryPath) try : _libraryPath(libraryPath), _handle(NULL) {
_handle = dlopen(_libraryPath.c_str(), RTLD_GLOBAL | RTLD_NOW);
if (!_handle)
throw DLLoaderException("On dlopen of " + _libraryPath, "DLLoader");
} catch (DLLoaderException &e) {
throw e;
};
T *getInstance(const std::string &entryPoint) const {
T *(*fptr)(void);
T *obj = NULL;
void *ret = dlsym(_handle, entryPoint.c_str());
if (!ret)
throw DLLoaderException("On dlsym of " + _libraryPath + dlerror() + "DLLoader");
fptr = reinterpret_cast<T *(*)(void)>(ret);
obj = dynamic_cast<T *>(fptr());
if (!obj)
throw DLLoaderException("On cast of " + _libraryPath + dlerror() + "DLLoader");
return (obj);
};
~DLLoader<T>() {
dlclose(_handle);
};
};
С этого момента мой DLLoader
работает. Моя проблема, если кто-то:
- создает
IDisplayModule
, но без getName
метода - создает динамическую c библиотеку с классом с именем
WrongClass
, который наследует из его IDisplayModule
Его WrongClass
не реализует метод getName
, и после того, как мой DLLoader
загрузил его библиотеку, моя программа падает, когда я вызовите метод getName
.
Я понимаю, почему он падает , но я хочу избежать этого. Как я могу обработать эту ошибку?
Вот моя тестовая функция:
int main(void)
{
try {
DLLoader<IDisplayModule> lib = DLLoader<IDisplayModule>("./wrongLib.so");
IDisplayModule *libInstance = lib.getInstance("entryPoint");
std::cout << libInstance->getName() << std::endl;
} catch (DLLoaderException &e) {
std::cerr << e.what() << std::endl;
}
}
и вот пример WrongClass
на wrongLib.so
:
class WrongClass : public IDisplayModule {
private:
std::string _name;
public:
lib1();
~lib1();
};
extern "C" {
IDisplayModule *entryPoint()
return (new WrongClass());
}