How to Pass an Std::String to Glshadersource

How to pass an std::string to glShaderSource?

data.c_str() returns a const char*, so do this:

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

How to pass String as GLchar** (char**) parameter in glShaderSource?

After half day search I found the work solution without compilation erros and bad memory access fails:

var cStringSource = (code as NSString).UTF8String
glShaderSource(shader, GLsizei(1), &cStringSource, nil)

C++ Passing std::string into Pointer-to-C-String Parameter

No, there's no way around it.

The function glShaderSource needs a pointer to a pointer to a character buffer (because it wants you to pass one or more C-strings), and you can't take the address of an rvalue (which is what the expression str.c_str() is).

But that's not really a problem, since in your final example all you're doing is assigning a pointer to a pointer. This is extremely cheap and easy.

Don't be afraid of "making a new variable" — naming things is good anyway.

Returning std::string from method non-deterministic behavior?

Replace

const char* fragmentSource = tools::read_file(_fragmentShaderPath).c_str();

with

std::string fragmentSourceStr = tools::read_file(_fragmentShaderPath);
const char* fragmentSource = fragmentSourceStr.c_str();

and the same thing for the vertexSource.

The issue is that the string you return is a temporary, so it is destroyed after you initialize fragmentSource with a pointer to its data, which makes fragmentSource point to an already destructed storage.

Segfault in glShaderSource

While C/C++ pointers and arrays behave the same way in many contexts, they are not the same. 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.

The type of the 3rd argument to glShaderSource() is const GLchar**, which means that you have to pass the address of a pointer variable. 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* 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.

openGL, GLFW, 1281 error on glShaderSource, the very next glShaderSource works fine somehow

You have to set vertexShader and fragmentShader to the result of glCreateShader instead of hardcoding it to 0 and 1.

GLuint vertexShader;
GLuint fragmentShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
std::cout <<"b " << glGetError() <<std::endl;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
std::cout <<"c " << glGetError() <<std::endl;

The function glCreateShader returns 0 if it the call was not successful.

In your code you set vertexShader hardcoded to 0, and opengl reports an error for glShaderSource(vertexShader, ... because you pass 0 as id to glShaderSource.

The 1281 is an GL_INVALID_VALUE error and is reported if shader is not a value generated by OpenGL. glShaderSource: Errors

Beside that you (const char**)&VertexShaderSource is wrong to get the memory address where a std::string stores the data you have to use .c_str():
How to pass an std::string to glShaderSource?

Same address, but different content

I've found the problem: the string returned by std::stringstream is temporary and is valid only until the end of the expression.

To expand the duration of validity of buffer.str(), it is possible to create a reference over the object. The life expectancy of the value will be extended to the one of the reference.

The following code works :

std::string const &string = buffer.str();
char const *code = string.c_str();
glShaderSource(id, 1, &code, 0);


Related Topics



Leave a reply



Submit