问题描述
对于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信息日志空结束符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!