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

How to load function with dlsym() without reinterpret_cast?

我正在尝试使用 clang-tidy 来执行 C++ 核心指南。虽然它确实有很多有效点,但有一件事我无法真正解决:dlsym returns a void* 我需要以某种方式将其转换为适当的函数指针。为此,我使用 reinterpret_cast。由于准则禁止这样做,因此我对此提出了警告。 当然,我可以在任何地方添加 //NOLINT 评论,但我正在寻找一种不使用 reinterpret_cast 的解决方案,这样警告就会消失。

这个问题有解决办法吗?

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

Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value.

这意味着符合标准的 C++ 编译器 必须 记录它是否 支持此功能。而且,如果它确实支持它,它 必须 记录它的行为方式。您可以依靠它在该编译器上以记录的方式工作(或不可用)。

关于核心准则 linting:如果您必须放置 //NOLINT "everywhere",那么这似乎意味着您在许多地方调用 naked 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;
}