我认为您需要在上述段落的上下文中阅读该行:
如果函数成功,则返回值是复制到缓冲区的字符串的长度,以字符为单位,不包括终止的空字符。如果缓冲区太小而无法容纳模块名称,则字符串将被截断为 nSize 个字符,包括终止空字符,函数返回 nSize,并且函数将最后一个错误设置为 ERROR_INSUFFICIENT_BUFFER。
Windows XP:如果缓冲区太小而无法容纳模块名称,则函数返回 nSize。最后一个错误代码仍然是 ERROR_SUCCESS。如果 nSize 为零,则返回值为零,最后一个错误代码为 ERROR_SUCCESS。
如果函数失败,则返回值为 0(零)。要获取扩展错误信息,请调用 GetLastError。
然后使用返回值和对 GetLastError() 的调用的组合来确定您是否有完整的路径。
如果你有一个完整的路径 ( ERROR_SUCCESS
) 并且return-value == nSize
你不应该假设它是空终止的。
在我看来,这主张永远不要假设它是空终止的。接口坏了。您发送给函数的缓冲区应该比 nSize 大一个字符。然后你可以空终止。
从 c++11 开始,std::basic_string<TCHAR>
保证附加一个尾随零,所以这样的事情应该做得很好:
std::basic_string<TCHAR> better_get_module_filename(HMODULE hModule)
{
std::basic_string<TCHAR> result(128, 0);
DWORD err = ERROR_SUCCESS;
do {
auto actual = GetModuleFileName(hModule, std::addressof(result[0]), result.size());
err = GetLastError();
if (actual == 0) {
throw "error of choice, wrapping err";
}
result.resize(actual);
} while(err == ERROR_INSUFFICIENT_BUFFER);
return result;
}