为啥为 C 程序定义 glGenVertexArrays 而不是 Linux 上的 C++ 程序?
Posted
技术标签:
【中文标题】为啥为 C 程序定义 glGenVertexArrays 而不是 Linux 上的 C++ 程序?【英文标题】:Why is glGenVertexArrays defined for a C program but not a C++ program on Linux?为什么为 C 程序定义 glGenVertexArrays 而不是 Linux 上的 C++ 程序? 【发布时间】:2014-06-03 16:55:06 【问题描述】:考虑以下文件:
#include <SDL.h>
#include <GLES2/gl2.h>
int main()
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("Test", 0, 0, 200, 200, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
SDL_GLContext context = SDL_GL_CreateContext(window);
GLuint vao;
glGenVertexArrays(1, &vao);
如果上面是test.c,那么下面这行(编译成C代码)就完美了:
gcc test.c -I/usr/include/SDL2 -lGLESv2 -lSDL2
然而,下一个(编译为 C++ 代码)不会:
gcc -x c++ test.c -I/usr/include/SDL2 -lGLESv2 -lSDL2
我得到的错误是:
test.c: In function ‘int main()’:
test.c:9:27: error: ‘glGenVertexArrays’ was not declared in this scope
glGenVertexArrays(1, &vao);
我正在使用 SDL 2.0 和 OpenGL ES 2.0 在 x86 Linux 上使用 gcc 4.8.2 进行编译。
发生了什么事?我进行的许多其他 OpenGL ES 2.0 调用(glDrawArrays、glGenBuffers 等)在 C 和 C++ 中都能很好地工作。此外,C++ 是否应该能够调用 C 库,尤其是(应该)旨在防止函数名称损坏的系统库?
出了什么问题,我该如何解决?
【问题讨论】:
完美运行?您至少需要使用 -Wall 进行编译才能声明。 @n.m.:-Wall
有误报和误报。
使用 -Wall 的误报比不使用的多,但漏报更少。为什么要用一个换另一个?您可以分析和抑制误报。
@n.m.,你是对的,-Wall
会使该函数调用变得可疑,我应该使用它(在我的辩护中,我已经习惯于使用带有 -Wall 的 Makefile 编译程序我这次忘记指定了)。
不是,唯一的区别是在C中是隐式声明(C++不这样做);它将通过编译阶段,但除非您链接到适当的库,否则它将无法在 C 中链接。glGenVertexArrays (...)
不是 OpenGL 2.0 或 OpenGL ES 2.0 的一部分,它已添加到 3.0在两者中。
【参考方案1】:
https://www.khronos.org/opengles/sdk/docs/man3/html/glGenVertexArrays.xhtml
前面的答案也是正确的,但并没有真正给出解决方案。实际上也不是我的。只是OpenGLES 2不支持glGenVertexArrays
。
解决方案:使用 OpenGL ES 3。
【讨论】:
就这么简单。谁会想到检查文档! @didierc 和 agrum,我没有检查文档 因为它在 C 下工作,这是它应该工作的方式!我的逻辑是,因为它在 C 下工作,所以(1)它必须在规范中,(2)它也必须在 C++ 下工作。尽管如此,感谢您的回答。 那是我当时很困惑。当你说它有效时,你的意思是它编译还是实际执行并完成工作? @agrum,如果驱动支持 GLES3,它可以很好地工作。 哦,是的,它会起作用,但到目前为止,InkBlend 一直在使用 OpenGLES 2,所以我怀疑it works
的含义。因为它不应该。【参考方案2】:
查看gl2.h
header,似乎没有定义上述功能。 C++ 在函数声明和定义方面有更严格的规则。在 C 语言中,您可以完美地使用事先未声明的函数,并且编译器将假定某个原型。在 C++ 中,任何函数都必须在使用之前至少声明。
C++ 规范的5.2.2 - 函数调用小节第 2 小节指出:
注意:如果使用函数或成员函数名称,并且名称查找(3.4)找不到声明 这个名字,程序格式不正确。这样的调用不会隐式声明任何函数。 ——尾注
这就是 C 的不同之处。然而,这可能表明一个更深层次的问题:要么您使用了错误的标头,并且链接到了支持该函数的 OpenGL 实现,或者以某种方式,标头应该包含该声明并且确实不是。我的第一个猜测是,您可能应该仔细检查您有效链接的 OpenGL 实现,以及您使用的标头是否正确。
但是,此 OpenGL 标准也可能将该函数的定义保留为扩展,或者该函数对链接器可见,因为驱动程序支持更高的标准或扩展。如果不先检查驱动程序是否确实支持相应的扩展,当然不建议依赖该功能。
【讨论】:
以上是关于为啥为 C 程序定义 glGenVertexArrays 而不是 Linux 上的 C++ 程序?的主要内容,如果未能解决你的问题,请参考以下文章
C语言中buffer到底是啥意思?是数组?缓冲区?为啥一般C程序中都不定义他直接拿来用呢?
单片机c语言程序中,数组最多能有几个元素?为啥我定定义了一个全局的数组,unsigned cha
为啥 C 或 C++ 标准不明确将 char 定义为有符号或无符号?