Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中简单的现代跨平台dlopen/loadLibrary包装器+;_C++_Cross Platform_Dynamic Library - Fatal编程技术网

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

C++ C+中简单的现代跨平台dlopen/loadLibrary包装器+;,c++,cross-platform,dynamic-library,C++,Cross Platform,Dynamic Library,我正在做一个跨平台的项目,我必须加载动态库。因此,我围绕dlopen/loadLibrary创建了一个非常基本的独立于平台的模板包装类,它的行为类似于工厂类,并返回lib对象的unique\u ptrs 但是,在大多数情况下,这是非常不实际的,因此我想知道,如何设计一个简单的包装器来实现以下功能: 当我们必须使用lib对象的多个实例时,加载lib并成为该lib对象实例上的工厂 当我们只想使用库对象的一个实例而不想使用工厂时,可以创建一个自管理实体(对象上包含唯一ptr的结构,库上可能包含句柄?

我正在做一个跨平台的项目,我必须加载动态库。因此,我围绕dlopen/loadLibrary创建了一个非常基本的独立于平台的模板包装类,它的行为类似于工厂类,并返回lib对象的
unique\u ptr
s

但是,在大多数情况下,这是非常不实际的,因此我想知道,如何设计一个简单的包装器来实现以下功能:

  • 当我们必须使用lib对象的多个实例时,加载lib并成为该lib对象实例上的工厂
  • 当我们只想使用库对象的一个实例而不想使用工厂时,可以创建一个自管理实体(对象上包含唯一ptr的结构,库上可能包含句柄?)
  • 使用库提供的删除器(符号“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 *);
};
}
#pragma一次
#包括
#包括
#如果是WIN32
#包括
#否则
#包括//dlopen
#恩迪夫
命名空间utils
{
模板
DynLib类
{
公众:
DynLib()=默认值;
~DynLib()
{
如果(处理)
closeLib(句柄);
};
私人:
bool printLibError()
{
#如果是WIN32
你考虑过吗?

它提供了如何实现插件/工厂方法的示例。

我相信您刚才已经描述了库。确切地说,libltdl:看看OpenGL加载程序库,它们是跨平台的,必须管理共享库和定位入口点。