Comments 19
PS: nullptr был ведён в с++11 ))
HANDLE CreateFileA(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
HANDLE hFile = CreateFile(szPath, GENERIC_READ, NULL, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
Хотите, поведаю, почему так?
NULL, как известно это дефайн для 0. Автор где-то нашел кусок [г]кода, где 3 и 4 параметры передавались как NULL. Ну с винапи древним кодом такое встречается повсеместно.
Потом как порядочный человек, думает «ну блин, на дворе 17 год, адекватные люди давно nullptr используют». И заменяет NULL везде на nullptr. Но к его сожалению, код не компилится (алилуйя, ради этого nullptr и придумали). Автор возвращает NULL в тех местах, где не собралось, в итоге имеем, что имеем)
Вот, например, ярчайший пример:
docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createfilemappinga
Функция на вход принимает handle, указатели и dwordы, возвращает тоже handle. При этом на входе просят передавать не NULL, а INVALID_HANDLE_VALUE в семантике, когда хэндла нет вообще. А на выходе при ошибке для того же типа возвращается NULL. Где здесь логика, я так и не понял. При этом в качестве дефолтного значения для флагов указывается конкретно целочисленный ноль, а не NULL. Легаси во всей красе, как по мне
Мне так всё это видится:
NULL всё таки больше подходит для указателей, так же как 0 для целочисленных типов. DWORD — это двойное слово, слово — 16бит(2байта) — имеем 32битное целое число, для которого лучше пользовать 0, нежели NULL.
Опять же, если упорно доказывать самому себе и окружающим, что NULL можно использовать везде в том числе и для целочисленных типов, то вас (не имею ввиду ИМЕННО ВАС) никто не будет закидывать гнилыми помидорами, но взгляните на этот код, и скажите, радует ли он ваш глаз/привычно ли оно выглядит:
int count = NULL;
Случай же с INVALID_HANDLE_VALUE на входе в CreateFileMappingA, скорее означает инициализацию, то есть первоначальное состояние; при возврате NULL — возврат есть ничто ( зачастую в Си такая практика: если указатель нулевой при возврате, — проверяй errno)
Т.е. почему нельзя сделать что-то вроде как в Qt сделано с opengl реализацией:
1) проверяем, есть ли реализация в системе
2) если ее нет или она нас не устраивает (LoadLibrary зафейлилась) — переименовываем OpenAL_dist.dll в OpenAL.dll в директории с программой. (ну это если мы в Roaming/пользовательской директории. Если нет, то да, надо права запросить — но один черт мы в систему не срем)
Что не так с предложенной идеей?
А с OpenAL, если не путаю, так игры поступают, через одну.
Уже хотел было спросить: как в драйвера теперь подписываете… А тут...
По драйвером я понимаю sys-файлы, которые имплементируют работу с каким-либо устройством
А здесь в статье речь про OpenAL.
Налицо — смешение понятий и их неконсистентное использование.
Ещё присоединюсь к оратору выше: в моих разработках хватало наличия разделяемых библиотек в каталоге приложения и их было необязательно закидывать в системный каталог (более того: это является плохим паттернов)
А получил «как сделать dll hell» и отказ от использования стандартного порядка поиска библиотек.
В заголовке опечатка, д.б. "0xc00007b", HEX-код ошибки же.
2gecube
Есть ещё "User Mode" драйвера, выглядят обычными dll.
Например, драйвер на звуковую карту стоит от производителя, а звук хочется выводить по-своему, используя, например, системный API или сторонний движок.
0xc00007b или установка драйверов из-под программы