让我有一个标题,例如#include <GL/gl.h>
.它包含 OpenGL API 函数的子集。我需要这样的东西:
static_assert(has_glDrawArraysIndirect::value, "There is no glDrawArraysIndirect");
或者更好:
PFNGLDRAWARRAYSINSTANCEDPROC ptr_glDrawArraysIndirect = ptr_to_glDrawArraysIndirect::ptr;
在哪里ptr_to_glDrawArraysIndirect::ptr
展开指向 glDrawArraysIndirect 的指针(如果已定义)或 stub 函数 stub_glDrawArraysIndirect
否则。
我的目标操作系统非常具体。任何基于链接器的解决方案(如 GetProcAddress
或 dlsym
)对我都不起作用,因为没有动态链接器。不止,我的驱动不提供glXGetProcAdrress
也不wglGetProcAddress
,基本上没有办法在运行时通过函数名查询指针(其实我想实现这样的机制)。
有什么想法吗?
最佳答案
这是一个可以在编译时检测到它并产生一个 bool 值的答案。它的工作原理是在命名空间中创建一个同名的模板函数,然后在 is_defined()
函数中使用该命名空间。如果真正的 glDrawArraysIndirect()
存在,它将优先于模板版本。如果您注释掉 glDrawArraysIndirect()
的第一个声明,底部的静态断言将触发。
#include <type_traits>
enum GLenum {};
void glDrawArraysIndirect(GLenum, const void*);
namespace detail {
struct dummy;
template<typename T>
dummy& glDrawArraysIndirect(T, const void*);
}
constexpr bool is_defined()
{
using namespace detail;
using ftype = decltype(glDrawArraysIndirect(GLenum(), nullptr));
return std::is_same<ftype, void>();
}
static_assert(is_defined(), "not defined");
稍微调整一下,您就可以将自定义函数设为模板并使用类似的技巧
#include <type_traits>
#include <iostream>
//#define USE_REAL
enum GLenum {TEST};
typedef void (*func_type)(GLenum, const void*);
#ifdef USE_REAL
void glDrawArraysIndirect(GLenum, const void*);
#endif
namespace detail {
struct dummy {};
template<typename T = dummy>
void glDrawArraysIndirect(GLenum, const void*, T = T())
{
std::cout << "In placeholder function" << std::endl;
}
}
void wrapDraw(GLenum x, const void* y)
{
using namespace detail;
glDrawArraysIndirect(x, y);
}
#ifdef USE_REAL
void glDrawArraysIndirect(GLenum, const void*)
{
std::cout << "In real function" << std::endl;
}
#endif
int main()
{
wrapDraw(TEST, nullptr);
}
关于c++ - 如何在编译时检查函数是否在全局范围内声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35944030/