[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