本文介绍了在std :: string中错误使用GL信息日志空结束符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于GL着色器和程序便利类,我有一个相当简单的 log()方法,因为相应的 compile 链接方法只返回 bool ,同时隐藏所有GL调用;例如

  std :: string 
glShader :: log()const
{
std :: string info;
GLint len = 0;

if(!glIsShader(gl_shader_obj))
info =(无效着色器对象)\\\
;
else
glGetShaderiv(gl_shader_obj,GL_INFO_LOG_LENGTH,& len);

if(len!= 0)
{
info.resize(static_cast< std :: string :: size_type>(len));
glGetShaderInfoLog(gl_shader_obj,len,NULL,& info [0]);
}

返回信息;
}

这是一个错误使用 std :: string :: resize(size_type)参数?我知道C ++ 11在查询时要求一个空的终止字符,即 c_str();但它是否保证它在存储中的存在?这可能是一种合理的方式来实现 string 来简化C字符串访问,但不是一个要求。



但是, GL_INFO_LOG_LENGTH 包括日志中字符数中的 \0 ,前提是存在日志;否则日志长度只是零。



我可能写入 string 的保留缓冲区在这种方式?我应该在 InfoLog 电话中使用(len - 1)吗?或者我有关于C ++ 11字符串的想法错了吗?也就是说,我可以用空终止符安全地覆盖吗?

解决方案

是的,这是 std :: string 。你可以获得一个指向第一个字符的指针,并写入字符数组,只要不超过范围[0, size())。 p>

但是,你犯了一个错误。请参阅 GL_INFO_LOG_LENGTH 在长度中包含NUL终结符。这意味着,从技术上讲,你的 std :: string 比它需要的字符长一个字符。 info 的最后一个字符将是一个NUL字符, std :: string 会处理它,



您应该 尝试解决这个问题,方法是从 len ,然后再设置 info 的大小。为什么?因为 glGetShaderInfoLog 将始终 NUL终止它写入的字符串。因此,如果你收缩 len ,它会从日志中截断最后一个实际字符。



从OpenGL复制

 信息后,收缩 info  resize(static_cast< std :: string :: size_type>(len)); 
glGetShaderInfoLog(gl_shader_obj,len,NULL,& info [0]);
info.pop_back();


I have a fairly simple log() method for a GL shader and program convenience classes, since the respective compile and link methods only return a bool, while hiding all the GL calls; e.g.,

std::string
glShader::log () const
{
    std::string info;
    GLint len = 0;

    if (!glIsShader(gl_shader_obj))
        info = "(invalid shader object)\n";
    else
        glGetShaderiv(gl_shader_obj, GL_INFO_LOG_LENGTH, & len);

    if (len != 0)
    {
        info.resize(static_cast<std::string::size_type>(len));
        glGetShaderInfoLog(gl_shader_obj, len, NULL, & info[0]);
    }

    return info;
}

Is this a misuse of the std::string::resize (size_type) argument? I known that C++11 mandates a null terminating character when queried, i.e., c_str(); but does it guarantee its presence in the storage? This might be a 'reasonable' way to implement string to simplify C string access, but not a requirement.

However, GL_INFO_LOG_LENGTH includes \0 in the number of characters in the log, provided there is a log; otherwise the log length is simply zero.

Am I potentially writing past the end of the string's reserved buffer in this fashion? Should I be using (len - 1) in the InfoLog call? Or do I have the idea about C++11 strings wrong? That is, can I safely overwrite with the null terminator?

解决方案

Yes, this is a valid use of std::string. You can get a pointer to the first character and write to the array of characters, so long as you don't exceed the range [0, size()).

However, you did make one mistake. See, GL_INFO_LOG_LENGTH includes the NUL terminator character in the length. Which means that, technically speaking, your std::string is one character longer than it needs to be. The last character of info will be a NUL character, and the std::string will treat that like it is part of the string's data, rather than a delimiter marking the end of the string.

You should not try to fix this by subtracting 1 from len before setting info's size. Why? Because glGetShaderInfoLog will always NUL terminate the string it writes. So if you shrink len, it will chop off the last actual character from the log.

Instead, you should shrink info after you've copied it from OpenGL:

info.resize(static_cast<std::string::size_type>(len));
glGetShaderInfoLog(gl_shader_obj, len, NULL, & info[0]);
info.pop_back();

这篇关于在std :: string中错误使用GL信息日志空结束符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 20:51