C ++中简单的现代跨平台dlopen / loadLibrary包装器

By simon at 2018-02-07 • 0人收藏 • 71人看过

我正在开发一个跨平台的项目,我必须加载动态 库。因此,我创建了一个非常基本的平台独立ntem模板 类似于工厂类的dlopen / loadLibrary封装类 返回lib对象的unique_ptr<T>s。 但在大多数情况下,这是非常不切实际的,所以我想知道如何 我可以设计一个简单的包装,可以做fol降脂:   加载一个lib,并成为该lib对象的实例的工厂,因为当我们必须使用l的多个实例ib对象   创建一个自我管理的实体(一个包含对象上的唯一ptr的结构和lib上的句柄可能?)fo当我们只想使用一个lib对象的一个​​实例,而不用打扰工厂   *使用库提供的deleter(symbol“destroy”)而不是默认的 这是否存在?如果不是的话,最好的办法是什么? 我的实现如此远:

#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 *);
};
}

1 个回复 | 最后更新于 2018-02-07
2018-02-07   #1

你有没有考虑过[Boost.DLL 库(http://www.boost.org/doc/libs/1660/doc/html/boost_dll.html)?它 提供了关于h的例子实现插件/工厂方法。

登录后方可回帖

Loading...