Редактировать Дэвид Шварц был прав: проблема заключается в том, что Еореп не вызывает GetLastError
- смотрите ниже
Хорошо, я увидел в комментариях к другим ответам, которые вы имеете в #define GetLastError() errno
. Вы должны были указать, что в начальном вопросе, поскольку errno
должен быть потокобезопасным Posix, но я не уверен, что он находится в Windows, когда я вижу это предупреждение в MSDN о глобальных переменных (включая errno
):
Эти глобальные переменные являются нежелательными для более безопасных функциональных версий, которые должны быть использованы вместо глобальной переменной
Но GetLastError
является поточно, просто Microsoft говорит:
Вы должны сразу вызвать функцию GetLastError, когда возвращаемое значение функции указывает, что такой вызов вернет полезные данные. Это связано с тем, что некоторые функции вызывают SetLastError с нулевым значением, когда они преуспевают, уничтожая код ошибки, установленный самой последней неудачной функцией.
Так что единственный надежный способ, чтобы иметь переменную локального, скажем lastError
и сделать:
if ((fParm = fopen(FullFileName.c_str(), "r")) == NULL)
{
int lastError = errno; // in reality calls GetLastError immediately and saves it current value even if other functions later calls SetLastError(0)
printf("%d", lastError);
}
EDIT:
В самом деле, fopen
не вызывает SetLastError
сам по себе. Вот демо проблемы:
#include <stdio.h>
#include <windows.h>
#include <errno.h>
int main() {
FILE *fd = fopen("", "r");
int lastErr = GetLastError();
int err = errno;
printf("errno : %d - GetLastError %d\n", err, lastErr);
return 0;
}
и результат:
errno : 22 - GetLastError 0
В самом деле, что виноват в #define GetLastError() errno
. Но в многопоточном приложении я настоятельно рекомендую немедленно скопировать errno
в локальную переменную.
fopen - это очень старый унаследованный код. Я не использую printf, мы записываем его в файл журнала - и я использовал его здесь только для упрощения вопроса – ArielB
Но бит 'c_str' - это не так! Конечно, если это наследие, оно используется для работы –
@EdHeal - полное имя файла - это пользовательский класс, который мы используем, он указывает на правильный символ *, но это не моя проблема. Я хочу сосредоточиться на том, почему это происходит. – ArielB