C++ 如何将 std::string 传递给 glShaderSource?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6047527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pass an std::string to glShaderSource?
提问by Rookie
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:
但它使我的程序崩溃。我如何转换std::string
为const char **
?我也试过, (const char **)&
但它说“需要 l 值”,我不明白。当我使用此代码时它工作正常:
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.
但我不能直接从std::string
. 我可以char
为它分配一个新数组,但这不是很好的代码。
I also tried with const GLchar
but obviously it makes no difference.
我也尝试过,const GLchar
但显然没有区别。
回答by Dark Falcon
data.c_str()
returns a const char*
, so do this:
data.c_str()
返回 a const char*
,所以这样做:
const char *c_str = data.c_str();
glShaderSource(shader, 1, &c_str, NULL);
回答by Jason
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 valueis 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.
的返回值std::string::c_str()
是指向保存在std::string
对象数据结构内的静态字符串数组的指针值(即地址)。由于返回值只是一个临时的 r 值(即,它只是一个存储在 CPU 寄存器中的数字),它不是一个 l 值,因此它没有内存地址,您可以实际获取其地址并进行转换指向一个指针。您首先必须将返回指针值保存在内存地址中。内存位置是左值,可以对它们应用地址运算符。所以这就是为什么你的第二个方法(或 Dark Falcon 的方法)起作用的原因,尽管记住返回的指针值是一个临时值,这意味着如果你对std::string
对象进行任何操作,它可能会使指针无效,因为std::string
对象在内部管理其数据结构的内存。因此,仅仅因为您已将返回指针值保存在内存位置并不意味着该指针在稍后的某个时间不会失效,并且在您可能无法确定性选择的点上。
回答by Rob?
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
,请这样做:
glShaderSource(shader, 1, StringHelper(data), NULL);
回答by mister why
glShaderSource
signature is, according to glShaderSource doc:
glShaderSource
根据glShaderSource 文档,签名是:
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*
).
其中string
“指定指向包含要加载到着色器的源代码的字符串的指针数组”。您要传递的是指向以 NULL 结尾的字符串的指针(即指向 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:
不幸的是,我不熟悉glShaderSource
,但我猜它不是指向“某些代码”的指针,而是像这样的:
const char** options =
{
"option1",
"option2"
// and so on
};
From opengl-redbook, you can read an example (I've shortened it in purpose):
从opengl-redbook,你可以阅读一个例子(我特意缩短了它):
const GLchar* shaderSrc[] = {
"void main()",
"{",
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;",
"}"
};
shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader, NumberOfLines(shaderSrc), shaderSrc, NULL);
回答by RedX
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.
我只想指出,返回的指针c_str()
只有在您不做任何需要重新分配 std::string 内部缓冲区的事情时才有效。这会使您获得的指针无效。
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.
只要您不离开 mychararr 的范围,这应该会很好地工作。
回答by Imagine Breaker
Shader.cpp
着色器.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
着色器.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
回答by Luis Tellez
Try using the .c_str() it give you a char * that you can use as it worked for you b4
尝试使用 .c_str() 它会给你一个 char * 你可以使用它,因为它对你有用 b4
#include <string>
void ConversionSample ()
{
std::string strTest ("This is a string");
const char* pszConstString = strTest.c_str ();
}