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

Roo*_*kie 28 c++ opengl string char

我有以下代码:

glShaderSource(shader, 1, (const char **)data.c_str(), NULL);
Run Code Online (Sandbox Code Playgroud)

但这会让我的程序崩溃.我怎么转换std::stringconst char **?我也试过, (const char **)&但它说"需要l值",我不明白.我使用这段代码时工作正常:

const char *data = "some code";
glShaderSource(shader, 1, &data, NULL);
Run Code Online (Sandbox Code Playgroud)

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

我也尝试过,const GLchar但显然它没有任何区别.

Dar*_*con 52

data.c_str()返回a const char*,所以这样做:

const char *c_str = data.c_str();
glShaderSource(shader, 1, &c_str, NULL);
Run Code Online (Sandbox Code Playgroud)

  • 我不认为你可以使用单线.`glShaderSource`需要一个字符串数组(`const char**`=`const char*`的数组),你的`std :: string`只给你一个字符串.你必须添加一个间接级别,以便`glShaderSource`获得一个指针,它可以取消引用以检索字符串. (6认同)
  • @Rob:注意`const char*c_str;`是_ [定义](http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration/1410632#1410632)_,而不是声明. (4认同)
  • 我完全赞同Ferdinand Beyer,因为`glShaderSource`的文档明确告诉你使用`const char*`数组. (3认同)

Jas*_*son 14

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

  • @ CharlesB:是的,返回值可以赋值给l值,但返回值本身不是l值,因此你不能将address-of运算符应用于`std :: string的返回: :c_str()`. (2认同)
  • 对不起,我只是觉得它可能有所帮助,并可能给出一些背景情况.OP想知道为什么一种方法有效,但另一种方法没有.打印有效的代码很好,但不一定给出一个工具或理解,以避免将来出现类似的情况.其他人已经创建了很好的代码示例,所以我想我会更深入地了解为什么一种方法有效,另一种方法不能帮助OP理解根本问题. (2认同)

Rob*_*obᵩ 11

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

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

然后,当你需要打电话时glShaderSource,这样做:

glShaderSource(shader, 1, StringHelper(data), NULL);
Run Code Online (Sandbox Code Playgroud)


mis*_*why 7

glShaderSource签名是,根据glShaderSource doc:

void glShaderSource(
    GLuint shader,
    GLsizei count,
    const GLchar** string,
    const GLint* length);
Run Code Online (Sandbox Code Playgroud)

where string"指定包含要加载到着色器的源代码的字符串的指针数组".您要传递的是指向NULL终止字符串的指针(即指向a的指针const char*).

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

const char** options =
{
    "option1",
    "option2"
    // and so on
};
Run Code Online (Sandbox Code Playgroud)

opengl-redbook中,您可以阅读一个示例(我已将其缩短为目的):

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