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

发布于 2024-11-08 02:12:48 字数 474 浏览 1 评论 0原文

我有以下代码:

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

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

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

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

我也尝试过使用 const GLchar 但显然它没有什么区别。

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:

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.

I also tried with const GLchar but obviously it makes no difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

画骨成沙 2024-11-15 02:12:48

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

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

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

const char *c_str = data.c_str();
glShaderSource(shader, 1, &c_str, NULL);
日记撕了你也走了 2024-11-15 02:12:48

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

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.

玩世 2024-11-15 02:12:48

您可以通过使用辅助类来获得看起来合理的调用。定义这个类:

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);

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);
信愁 2024-11-15 02:12:48

glShaderSource 签名是,根据 glShaderSource doc

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

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

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

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

来自 opengl-redbook,您可以阅读一个示例(我故意缩短了它):

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

glShaderSource signature is, according to glShaderSource doc:

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*).

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:

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

From opengl-redbook, you can read an example (I've shortened it in purpose):

const GLchar* shaderSrc[] = {
    "void main()",
    "{",
    "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;",
    "}"
};
shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader, NumberOfLines(shaderSrc), shaderSrc, NULL);
放肆 2024-11-15 02:12:48

我只想指出,只有当您不执行任何需要重新分配 std::string 内部缓冲区的操作时,c_str() 返回的指针才有效。这会使你得到的指针无效。

但由于您确实需要 ** 我会这样做:

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

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

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.

梦中的蝴蝶 2024-11-15 02:12:48

尝试使用 .c_str() 它会给你一个 char * ,你可以使用它,因为它对你有用 b4

#include <string>

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

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 ();
 }
吃→可爱长大的 2024-11-15 02:12:48

着色器.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);
}

着色器.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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文