How to pass an std::string to glShaderSource?

后端 未结 7 1823
感情败类
感情败类 2020-12-05 04:47

I have the following code:

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

But it makes my program crash. How do I convert

相关标签:
7条回答
  • Try using the .c_str() it give you a char * that you can use as it worked for you b4

    #include <string>
    
    void ConversionSample ()
    {
     std::string strTest ("This is a string");
     const char* pszConstString = strTest.c_str ();
     }
    
    0 讨论(0)
  • 2020-12-05 05:04

    Shader.cpp

    #include "Shader.hpp"
    
    Shader::Shader(GLenum type)
    {
        this->_type = type;
    }
    Shader::~Shader() {}    
    
    GLuint Shader::get(char* filename)
    {
        GLuint shdr = glCreateShader(this->_type);
        FILE* f = 0;
        f = fopen(filename, "r+");
        char* str_tmp = 0;
        char** shdr_text = 0;
        shdr_text = (char**)malloc(sizeof(char**) * 255);
        str_tmp = (char*)malloc(sizeof(char*) * 255);
        int i = 0, ch = 0, n = 0;
    
        for(i = 0; i < 255; ++i){ *(shdr_text + i) = (char*)malloc(sizeof(char*) * 255); }
    
        i = 0;
        while((ch = fgetc(f)) != EOF)
        {
            sprintf(str_tmp, "%s%c", str_tmp, ch);
            if(ch == (int)'\n' || ch == (int)'\r')
            {
                sprintf(*(shdr_text + i), "%s", str_tmp);
                sprintf(str_tmp, "");
                ++i;
            }
        }
    
        free(str_tmp);
        fclose(f);
    
        glShaderSource(shdr, i, const_cast<const GLchar**>(shdr_text), 0);
        glCompileShader(shdr);
    
        free(shdr_text);
    
        return(shdr);
    }
    

    Shader.hpp

    #ifndef SHADER_HPP
    #define SHADER_HPP
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <GL/glew.h>
    #include <GL/gl.h>
    
    class Shader
    {
        public:
            Shader(GLenum type);
            virtual ~Shader();
    
            GLuint get(char* filename);
    
        private:
            GLenum _type;
    };
    
    #endif
    
    0 讨论(0)
  • 2020-12-05 05:10

    I only want to point out that the pointer returned by c_str() is only valid as long as you don't do anything that requires reallocation of the internal buffer of std::string. That invalidates the pointer you got.

    But since you really require a ** i would do this:

    const char* mychararr[1] = {data.c_str()};
    glShaderSource(shader, 1, mychararr, NULL);
    

    That should work nicely as long as you don't leave the scope of mychararr.

    0 讨论(0)
  • 2020-12-05 05:13

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

    const char *c_str = data.c_str();
    glShaderSource(shader, 1, &c_str, NULL);
    
    0 讨论(0)
  • 2020-12-05 05:14

    You can get a reasonable-looking call by using a helper class. Define this class:

    struct StringHelper {
      const char *p;
      StringHelper(const std::string& s) : p(s.c_str()) {}
      operator const char**() { return &p; }
    };
    

    Then, when you need to call glShaderSource, do it this way:

    glShaderSource(shader, 1, StringHelper(data), NULL);
    
    0 讨论(0)
  • 2020-12-05 05:16

    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.

    0 讨论(0)
提交回复
热议问题