How to pass an std::string to glShaderSource?

2019-01-13 20:43发布

I have the following code:

glShaderSource(shader, 1, (const char **)data.c_str(), NULL);

But it makes my program crash. How do I convert std::string into const char ** ? I also tried (const char **)& but it said "requires l-value" which I don't understand. It works fine when I use this code:

const char *data = "some code";
glShaderSource(shader, 1, &data, NULL);

But I can't make it work directly from a std::string. I could allocate a new char array for it but that is not nice code.

I also tried with const GLchar but obviously it makes no difference.

8条回答
聊天终结者
2楼-- · 2019-01-13 21:18

The return value of std::string::c_str() is a pointer value (i.e., an address) to a static string array held inside the data-structures of the std::string object. Since the return value is just a temporary r-value (i.e., it's just a number stored in a CPU register), it is not an l-value and therefore it does not have a memory address you can actually take the address of and cast to a pointer-to-pointer. You first must save the return pointer value in a memory address. Memory-locations are l-values, and can have the address-of operator applied to them. So that is why your second method (or Dark Falcon's method) works, although keep in mind that the pointer value returned is a temporary, meaning that if you do any operations on the std::string object, it could invalidate the pointer since the std::string object internally manages the memory of its data-structures. So just because you've saved the return pointer value in a memory location doesn't mean that the pointer won't be invalidated at some later time, and at a point that you may not be capable of deterministically choosing.

查看更多
爷、活的狠高调
3楼-- · 2019-01-13 21:19

glShaderSource signature is, according to glShaderSource doc:

void glShaderSource(
    GLuint shader,
    GLsizei count,
    const GLchar** string,
    const GLint* length);

where string "Specifies an array of pointers to strings containing the source code to be loaded into the shader". What you're trying to pass is a pointer to a NULL terminated string (that is, a pointer to a const char*).

Unfortunately, I am not familiar with glShaderSource, but I can guess it's not expected a pointer to "some code" but something like this instead:

const char** options =
{
    "option1",
    "option2"
    // and so on
};

From opengl-redbook, you can read an example (I've shortened it in purpose):

const GLchar* shaderSrc[] = {
    "void main()",
    "{",
    "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;",
    "}"
};
shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader, NumberOfLines(shaderSrc), shaderSrc, NULL);
查看更多
登录 后发表回答