如何在不使用reinterpret_cast的情况下使用dlsym()加载函数?

时间:2019-03-26 17:21:58

标签: c++ clang-tidy

我正在尝试使用clang-tidy来实施C ++核心准则。尽管它确实有很多有效的观点,但我无法真正解决一件事:dlsym返回一个void*,我需要以某种方式将其转换为适当的函数指针。为此,我使用reinterpret_cast。由于指南禁止这样做,因此我对此有警告。 当然,我可以在任何地方添加//NOLINT注释,但是我正在寻找一种不使用reinterpret_cast的解决方案,以便消除警告。

有没有解决此问题的方法?

1 个答案:

答案 0 :(得分:6)

reinterpret_cast外,没有其他方法可以将函数指针类型转换为对象指针类型。这样做是实现定义的行为[expr.reinterpret.cast]/8

  

有条件地支持将函数指针转换为对象指针类型,反之亦然。这种转换的含义是实现定义的,除非如果实现支持双向转换,则将一种类型的prvalue转换为另一种类型的prvalue,然后再转换回去(可能具有不同的cv限定条件)将产生原始指针值。 / p>

这意味着如果C ++编译器不支持此功能,则该文件必须是 。而且,如果它确实支持它,那么它必须 记录其行为的精确度。您可以依靠它以书面形式在该编译器上工作(或不可用)。

关于核心准则的内容:如果您必须将//NOLINT放在“各处”,那么这似乎意味着您在许多地方都称裸dlsym()。考虑将其包装,例如

template <typename T>
inline T* lookupSymbol(void* module, const char* name)
{
    auto symbol = reinterpret_cast<T*>(dlsym(module, name));  // NOLINT

    if (!symbol)
        throw std::runtime_error("failed to find symbol '"s + name + '\'');

    return symbol;
}