Непонятный крайний случай GetModuleFileName

Документы MSDN государство:

lpFilename [out]

Указатель на буфер, который получает полный путь к модулю. Если длина пути меньше размера, указанного параметром nSize, функция завершается успешно и путь возвращается в виде строки с нулевым символом в конце.

Если длина пути превышает размер, указанный параметром nSize, функция завершается успешно, и строка усекается до символов nSize, включая завершающий нулевой символ.

Windows XP: строка усекается до символов nSize и не заканчивается нулем.

Это неоднозначно. Должен ли я интерпретировать это, что строка никогда прекращается в Windows XP? Или это только не заканчивается нулем, когда строка усекается?

Я был бы признателен, если кто-то знает справочную версию, или где-то работает под управлением Windows XP, и может просто проверить поведение.

0

Решение

Я думаю, что вам нужно прочитать эту строку в контексте пункта выше:

Если функция завершается успешно, возвращаемое значение — это длина строки, которая копируется в буфер, в символах, не включая завершающий нулевой символ. Если буфер слишком мал для хранения имени модуля, строка усекается до символов 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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]