简体   繁体   English

glShaderSource 中的段错误

[英]Segfault in glShaderSource

Alright I have loaded up a glVertex shader, as a const char string from a hexdump.好的,我已经加载了一个 glVertex 着色器,作为来自十六进制转储的 const 字符字符串。 However I get a compiler error from the following code, and I can't figure out why it refuses to compile this, with an error of:但是我从下面的代码中得到一个编译器错误,我无法弄清楚为什么它拒绝编译它,错误是:

main.cpp: In function ‘void loadShaders()’:
main.cpp:27:55: error: cannot convert ‘const char (*)[92]’ to ‘const GLchar** {aka const char**}’ in argument passing
     glShaderSource(vertexShader, 1, &vertex_glsl, NULL);                                                           ^

But when I override the error by casting &vertex_glsl to (const char**) , it will compile but segfault on runtime.但是当我通过将&vertex_glsl(const char**)来覆盖错误时,它会编译但在运行时出现段错误。 Why would this segfault?为什么会出现这个段错误?

const char vertex_glsl[] = {
  0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x35, 0x30,
  0x0a, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x6f,
  0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69,
  0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x7b, 0x0a, 0x20, 0x20,
  0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
  0x6e, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x70, 0x6f, 0x73,
  0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20,
  0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x00
};
const int vertex_glsl_len = 92;

void loadShaders(){
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);

    // here's where it segfaults
    glShaderSource(vertexShader, 1, &vertex_glsl, NULL);
    glCompileShader(vertexShader);
}

While C/C++ pointers and arrays behave the same way in many contexts, they are not the same.尽管 C/C++ 指针和数组在许多上下文中的行为方式相同,但它们并不相同。 What you stumbled over here, with both the initial compile error and with the crash after adding the type cast, is one example of where the two are different:你在这里偶然发现的,包括初始编译错误和添加类型转换后的崩溃,是两者不同的一个例子:

  • The & operator applied to an array gives you the address of the array , which is a pointer to the data stored in the array.&应用于阵列操作者给你阵列,这是一个指向存储在所述阵列中的数据的地址。 The actual address (but not the type) resulting from applying the operator is the same as the address of the first element in the array.应用运算符产生的实际地址(但不是类型)与数组中第一个元素的地址相同。 So with this declaration:所以有了这个声明:

     char s[] = "abc";

    the following two expressions:以下两个表达式:

     &s &s[0]

    result in the same address.结果是同一个地址。 Again, the type of the two expressions is different, with the first being a pointer to an array, and the second a pointer to a character, but the address is the same.同样,两个表达式的类型不同,第一个是指向数组的指针,第二个是指向字符的指针,但地址是相同的。

  • The & operator applied to a pointer variable gives you the address of the pointer variable.应用于指针变量的&运算符为您提供指针变量的地址。 Following up on the same example:跟进同一个例子:

     char s[] = "abc"; char* t = s;

    the following two expressions:以下两个表达式:

     &t &t[0]

    result in different addresses.导致地址不同。 The first one is the address of the pointer variable t , while the second one is again a pointer to the first character, which is the same as &s[0] above.第一个是指针变量t的地址,而第二个也是指向第一个字符的指针,与上面的&s[0]相同。

The type of the 3rd argument to glShaderSource() is const GLchar** , which means that you have to pass the address of a pointer variable. glShaderSource()的第三个参数的类型是const GLchar** ,这意味着您必须传递指针变量的地址。 The compile error you got in your first attempt was a serious error, because you really were passing a value of the wrong type (a pointer to an array).您在第一次尝试中遇到的编译错误是一个严重错误,因为您确实传递了错误类型的值(指向数组的指针)。 Adding the type cast just let the broken code pass through the compiler, and caused a crash at runtime instead.添加类型转换只会让损坏的代码通过编译器,而导致运行时崩溃。

To make this work, you need to assign the string to a variable of type const GLchar* , and pass the address of that variable:要完成这项工作,您需要将字符串分配给类型为const GLchar*的变量,并传递该变量的地址:

const GLchar* vertex_glsl_ptr = vertex_glsl;
glShaderSource(vertexShader, 1, &vertex_glsl_ptr, NULL);

This will now compile without a type cast, and will not crash when you run it.这现在将在没有类型转换的情况下编译,并且在您运行它时不会崩溃。

Try:尝试:

glShaderSource(vertexShader, 1, &vertex_glsl, &vertex_glsl_len);

The problem might simply be that in this case it should not be driven by null terminated string but a size defined string.问题可能只是在这种情况下它不应该由空终止字符串驱动,而是由大小定义的字符串驱动。

Your char array terminates the string at each line .您的字符数组在每一行终止字符串

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM