C 中的简单现代跨平台Dlopen/LoadLibrary包装器



我正在研究一个跨平台项目,我必须加载动态库。因此,我创建了一个非常基本的平台独立的模板包装类,围绕dlopen/loadlibrary,其作用类似于工厂类,并返回lib对象的 unique_ptr<T> s。

,但在大多数情况下,这是非常不可行的,我想知道,我如何设计一个可以执行以下操作的简单包装器:

  • 加载lib并成为该lib对象实例的工厂,因为我们必须使用lib对象的多个实例
  • 创建一个自我管理的实体(一个在对象上包含唯一PTR的结构,也许是LIB上的句柄?(
  • 使用提供的库提供的eleter(符号"销毁"(,而不是默认一个

这是否存在?如果不是,那么最好的方法是什么?

到目前为止我的实施:

#pragma once
#include <memory>
#include <iostream>
#if _WIN32
#include <Windows.h>
#else
#include <dlfcn.h> //dlopen
#endif
namespace utils
{
template <class T>
class DynLib
{
  public:
    DynLib() = default;
    ~DynLib()
    {
        if (handle_)
            closeLib(handle_);
    };
  private:
    bool printLibError()
    {
#if _WIN32
        std::cerr << GetLastError() << std::endl;
#else
        std::cerr << dlerror() << std::endl;
#endif
        return false;
    }
    void *openLib(const std::string &libName)
    {
#if _WIN32
        return LoadLibrary((libName + ".dll").c_str());
#else
        return dlopen((libName + ".so").c_str(), RTLD_LAZY);
#endif
    }
    int closeLib(void *libHandle)
    {
#if _WIN32
        return FreeLibrary((HMODULE)libHandle);
#else
        return dlclose(libHandle);
#endif
    }
    void *loadSymbol(void *libHandle, const char *sym)
    {
#if _WIN32
        return (void *)GetProcAddress((HMODULE)libHandle, sym);
#else
        return dlsym(libHandle, sym);
#endif
    }
  public:
    bool open(const std::string &filename, const char *csym = "create", const char *dsym = "destroy")
    {
        if (!(handle_ = openLib(filename)))
            return printLibError();
        if (!(create = (T * (*)()) loadSymbol(handle_, csym)))
            return printLibError();
        if (!(destroy_ = (void (*)(T *))loadSymbol(handle_, dsym)))
            return printLibError();
        return true;
    }
    std::unique_ptr<T> createUnique()
    {
        return (std::unique_ptr<T>(create()));
    }
  private:
    void *handle_{nullptr};
    T *(*create)();
    void (*destroy_)(T *);
};
}

您是否考虑过boost.dll库?它提供了有关如何实施插件/工厂方法的示例。

最新更新