如何在没有 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;
}
我正在尝试使用 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;
}