【问题标题】:C/C++ function dynamic loader (helper)C/C++ 函数动态加载器(助手)
【发布时间】:2020-02-23 20:33:13
【问题描述】:

我尝试实现一个帮助类来轻松加载 .dll 或 .so 文件并获取函数指针。 以下代码在 ubuntu 16 和 VS'2015 上编译并运行良好,但我在 Centos 7(旧 GCC 4.8.5)上编译时遇到问题....

它抱怨

template< class T> constexpr bool ext_is_function_v = is_function<T>::value;

错误消息(见下文)没有给出失败原因的任何线索!

错误:constexpr bool ext_is_function_v = is_function::value 的模板声明;

是 constexpr 吗?还是模板别名?我查看了 GCC4.8 支持的 C++11 功能,一切似乎都很好。但是 CodeExplorer 报告了 usingconstexpr

的问题

欢迎任何想法

完整代码:

#include <type_traits>
namespace std { /* std lib extension with 2 helpers C++14 or C++17*/
    template< bool B, class T = void >
    using ext_enable_if_t = typename enable_if<B, T>::type;
    template< class T> constexpr bool ext_is_function_v = is_function<T>::value;
}
#if defined(_WIN64) || defined(_WIN32)
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#else
#include <dlfcn.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#endif
template<typename F_PTR_T>
class ProcPtr {
public:
    explicit ProcPtr(F_PTR_T ptr) : _ptr(ptr) {}
    template <typename T, typename = std::ext_enable_if_t<std::ext_is_function_v<T>>>
    operator T *() const { return reinterpret_cast<T *>(_ptr); }
private:
    F_PTR_T _ptr;
};
template<typename MODULE_T, typename F_PTR_T>
class DllHelper {
public:
    explicit DllHelper(const char* filename) :
#if defined(_WIN64) || defined(_WIN32)
        _module(LoadLibrary(filename)) 
#else
        _module(dlopen(filename, RTLD_LAZY)) 
#endif
    {
        if(_module == NULL) {
            throw std::runtime_error((boost::format("Error while loading %1%") % filename).str().c_str());
        }
    }

    ~DllHelper() {
#if defined(_WIN64) || defined(_WIN32)
        FreeLibrary(_module);
#else
        dlclose(_module);
#endif
    }

    ProcPtr<F_PTR_T> operator[](const char* proc_name) const {
#if defined(_WIN64) || defined(_WIN32)
        return ProcPtr<F_PTR_T>(GetProcAddress(_module, proc_name));
#else
        return ProcPtr<F_PTR_T>(dlsym(_module, proc_name));
#endif
    }

private:
    MODULE_T _module;
};

【问题讨论】:

  • 自 C++14 起就存在变量模板。
  • 并将代码放在命名空间std 是UB(此处不适用例外)。
  • 但是如果没有该功能,是否可以拥有相同的功能?
  • is_function&lt;T&gt;::value而不是ext_is_function_v&lt;T&gt;?

标签: c++ c++11 templates gcc


【解决方案1】:

最后,我只是回到 C++11 而不尝试扩展 std 命名空间。

#if defined(_WIN64) || defined(_WIN32)
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#else
#include <dlfcn.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#endif
template<typename F_PTR_T>
class ProcPtr {
public:
    explicit ProcPtr(F_PTR_T ptr) : _ptr(ptr) {}
    template <typename T, typename = typename std::enable_if< std::is_function<T>::value >::type >
    operator T *() const { return reinterpret_cast<T *>(_ptr); }
private:
    F_PTR_T _ptr;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2019-05-31
    • 1970-01-01
    • 2020-08-26
    • 2013-01-19
    • 1970-01-01
    相关资源
    最近更新 更多