[plug] [PATCH] added library loader
Vladislav Ivanishin
vlad at ispras.ru
Fri Apr 6 13:22:39 MSK 2018
Здравствуйте, Андрей,
Небольшое замечание к Вашему патчу:
> ---
> Loader.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++
> Loader.h | 26 ++++++++++++++++++++++++++
> 2 files changed, 68 insertions(+)
> create mode 100644 Loader.cpp
> create mode 100644 Loader.h
>
> diff --git a/Loader.cpp b/Loader.cpp
> new file mode 100644
> index 0000000..00b99e2
> --- /dev/null
> +++ b/Loader.cpp
> @@ -0,0 +1,42 @@
> +#include "Loader.h"
> +
> +#ifndef WIN32
> +#include <dlfcn.h>
> +#else
> +#include <windows.h>
> +#endif
> +
> +Loader::~Loader() {
> + for(unsigned I = 0; I < mLibs.size(); ++I) {
> + #ifndef WIN32
> + dlclose(mLibs[I]);
> + #else
> + FreeLibrary((HINSTANCE)mLibs[I]);
> + #endif
> + }
> +}
> +
> +void Loader::loadRun(const std::vector<const char*>& passes) {
> + for(unsigned I = 0; I < passes.size(); ++I) {
> + void *Lib;
> + passGetter Fun;
> + #ifndef WIN32
> + Lib = dlopen(passes[I], RTLD_LAZY);
Есть ли какая-то причина использовать ленивое связывание? На мой взгляд,
режим, задаваемый флагом RTLD_NOW, предпочтительнее, поскольку тогда
пользователь сразу обнаружит ошибку, если плагин ссылается на функии, не
определённые в QBE. Такая ситуация может возникнуть, например, если
автор планига пользовался устаревшей версией хедеров.
Более подробную диагностику можно возвращать с помощью `dlerror()`.
> + #else
> + Lib = LoadLibrary(passes[I]);
> + #endif
> + if(!Lib)
> + throw Error(Error::OpenLibraryErr, passes[I]);
> + mLibs.push_back(Lib);
> + #ifndef WIN32
> + Fun = (passGetter)dlsym(Lib, "getPass");
> + #else
> + Fun = (passGetter)GetProcAddress((HINSTANCE)Lib, "getPass");
> + #endif
> + if(Fun == NULL) {
> + throw Error(Error::FunctionLoadErr, "getPass");
> + } else {
> + mPassKeeper.launchPass(Fun);
> + }
> + }
> +}
> diff --git a/Loader.h b/Loader.h
> new file mode 100644
> index 0000000..93dbafe
> --- /dev/null
> +++ b/Loader.h
> @@ -0,0 +1,26 @@
> +#ifndef LOADER_H
> +#define LOADER_H
> +
> +#include "provider.h"
> +#include <vector>
> +
> +struct Error {
> + enum ErrorTy {OpenLibraryErr = 0, FunctionLoadErr};
> + Error(ErrorTy E, const char* N) : Err(E), Name(N) {};
> + ErrorTy Err;
> + const char* Name;
> +};
> +
> +class Loader {
> + std::vector<void*> mLibs; //all of the opened libs
> + PassKeeper mPassKeeper;
> +public:
> + Loader();
> + ~Loader(); //close opened libs
> +
> + //launch all of given passes by PassKeeper.launchPass
> + void loadRun(const std::vector<const char*>& passes);
> +};
> +
> +
> +#endif //LOADER_H
--
Влад
More information about the plug
mailing list