在源代码中,调用函数时不带 ()。文档给出了 1 个必需的参数

In source code, function is called with no (). Documentation gives 1 required argument

我正在学习 OpenGL 开发,在研究一些示例源代码时,有一行我似乎无法理解。它涉及使用 GLFW 初始化 GLAD。下面是整个代码块。

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
}

因此,据我所知,if 语句中的代码旨在初始化 GLAD,return 如果初始化成功则为 1,以便轻松处理错误。凉爽的。不过,我感到困惑的是这个 gladLoadGLLoader 函数的输入,即:

(GLADloadproc)glfwGetProcAddress

做了一些研究,GLADloadproc return 没有任何用处,但是 glfwGetProcAddress 在 GLFW 文档 here 中有一个条目,据此,它是一个函数并定义1 个必需参数。我认为这很奇怪,因为在源代码中它甚至不像一个函数;看起来 glfwGetProcAddress 是一个变量(或者对象?)被转换为 GLADloadproc 类型。做一些反省,我 运行 以下打印:

std::cout << glfwGetProcAddress << std::endl;
std::cout << typeid(glfwGetProcAddress).name() << std::endl;

输出:

00AE1172
void (__cdec*__cdecl(char const *))(void)

所以我可以看到调用 glfwGetProcAddress 实际上是 return 看起来像地址的东西,但是尝试将其调用为 glfwGetProcAddress() 失败并且并不令人震惊地需要一个论点。当查看这个假设地址的类型时,我绝对不明白。所以我很乐意使用它,因为它显然有效并且在官方文档和教程中直接引用,但我真的很想了解这里发生了什么,如果有人碰巧比我有更好的想法。

typedef void* (* GLADloadproc)(const char *name);

这不仅仅是任何旧的指针类型:这是一个 function 指针类型。在您的代码中,您 调用 函数 gladLoadGLLoader,但 传递 glfwGetProcAddress 的地址。 gladLoadGLLoader 现在可以随时调用您传递给它的参数,并使用它想要的任何参数。你自己实际上并不是在调用 glfwGetProcAddress.

在此上下文中,glfwGetProcAddress 是一个 'callback',并且 gladLoadGLLoader 注册了该回调。

OpenGL 扩展(以及在某些操作系统上,OpenGL 1.1 配置文件中未定义的每个函数)必须 loaded at runtime. This means that one has to query the address of each of these functions through the appropriate operating system api (wgl/glx/...). The result is than a function pointer 才能用于调用该函数。

GLAD 现在是一个为您处理此函数指针加载的库。但是为了能够查询函数指针,它需要知道应该使用哪种方法来检索它们(如前所述,这取决于操作 system/window api)。 gladLoadGLLoader 的第一个参数是指向函数的函数指针,该函数用于按名称检索 OpenGL 函数指针。 gladLoadGLLoader然后调用这个函数(指针)查询其他函数指针。

在 glfw 的情况下,使用的函数是 glfwGetProcAddress,但也可以在使用 glut 时传递 glutGetProcAddress 或在使用 SDL 时传递 SDL_GL_GetProcAddress