如何将std :: string传递给glShaderSource?

时间:2011-05-18 15:52:59

标签: c++ string opengl char

我有以下代码:

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

但它让我的程序崩溃了。如何将std::string转换为const char **? 我也试过(const char **)&,但它说“需要l值”,我不明白。我使用这段代码时工作正常:

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

但我无法直接从std::string开始工作。我可以为它分配一个新的char数组,但这不是很好的代码。

我也试过const GLchar,但显然没有区别。

8 个答案:

答案 0 :(得分:49)

data.c_str()会返回const char*,所以请执行以下操作:

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

答案 1 :(得分:14)

std::string::c_str()的返回值是保持在std::string对象的数据结构内的静态字符串数组的指针值(即地址)。由于返回只是一个临时r值(即,它只是一个存储在CPU寄存器中的数字),它不是l值,因此它没有内存地址你可以实际上取地址并转换为指向指针的指针。首先必须将返回指针值保存在内存地址中。内存位置是l值,可以应用地址运算符。这就是为什么你的第二种方法(或Dark Falcon的方法)有效,但请记住返回的指针值是临时的,这意味着如果对std::string对象执行任何操作,它可能会使指针无效std::string对象在内部管理其数据结构的内存。因为你已经将返回指针值保存在内存位置并不意味着指针不会在以后某个时间失效,并且在某些时候你可能无法确定性地选择。

答案 2 :(得分:11)

通过使用帮助程序类,您可以获得看似合理的调用。定义这个类:

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

然后,当您需要致电glShaderSource时,请这样做:

glShaderSource(shader, 1, StringHelper(data), NULL);

答案 3 :(得分:7)

根据{{​​3}},

glShaderSource签名:

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

其中string“指定一个指向字符串的指针数组,其中包含要加载到着色器中的源代码”。您要传递的是指向以NULL结尾的字符串的指针(即指向const char*的指针)。

不幸的是,我对glShaderSource并不熟悉,但我可以猜测它不是指向“某些代码”的指针而是这样的东西:

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

glShaderSource doc,您可以阅读一个示例(我已将其缩短为目的):

const GLchar* shaderSrc[] = {
    "void main()",
    "{",
    "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;",
    "}"
};
shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader, NumberOfLines(shaderSrc), shaderSrc, NULL);

答案 4 :(得分:2)

我只想指出c_str()返回的指针只有在你不做任何需要重新分配std :: string内部缓冲区的事情时才有效。这会使你得到的指针无效。

但是因为你真的需要**我会这样做:

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

只要你不离开mychararr的范围,这应该可以很好地工作。

答案 5 :(得分:1)

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

答案 6 :(得分:0)

尝试使用.c_str()它会为你提供一个你可以使用的char * b4

#include <string>

void ConversionSample ()
{
 std::string strTest ("This is a string");
 const char* pszConstString = strTest.c_str ();
 }

答案 7 :(得分:-3)

使用字符串的地址并进行投射也可以在一行中使用:

glShaderSource(vertexShader, 1, (const char* const*)&vertexSource, NULL);