Pull to refresh

Comments 19

Зачем мешать NULL и nullptr? Используйте что-нибудь одно.

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 в тех местах, где не собралось, в итоге имеем, что имеем)
Я не спец по WinAPI, но на месте автора, я бы не пользовал NULL для типа DWORD ))
А почему нет? В документации WinAPI везде предлагают использовать NULL, потому что он взаимозаменяем с нулем, но добавляет наглядность в духе «тут ничего нет».
Ну тут спорный вопрос, обычно нужно смотреть документацию к конкретной функции, бывает, что для семантики «тут ничего нет» нужно указывать не NULL, а вообще какой-нибудь INVALID_HANDLE_VALUE, который даже нулю не равен.
Вот, например, ярчайший пример:
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)

Можете объяснить одну вещь — разве нахождения OpenAL*.dll в директории с исполняемыми файлами недостаточно? Зачем ее вообще необходимо в системную директорию-то копировать?
Т.е. почему нельзя сделать что-то вроде как в Qt сделано с opengl реализацией:
1) проверяем, есть ли реализация в системе
2) если ее нет или она нас не устраивает (LoadLibrary зафейлилась) — переименовываем OpenAL_dist.dll в OpenAL.dll в директории с программой. (ну это если мы в Roaming/пользовательской директории. Если нет, то да, надо права запросить — но один черт мы в систему не срем)

Что не так с предложенной идеей?
Вместо переименования не лучше ли положить в отдельную папку, а потом оттуда загружать через LoadLibrary с указанием полного пути?
Вообще, у OpenAL там не только 1 dll. Тут код для примера местами был.
И именно так очень часто делают с библиотеками MSVCP (штук по 5 бывает сразу лежит), правда, похоже, что многие и не проверяют, есть ли они в системе, но это уже другой вопрос :).
А с OpenAL, если не путаю, так игры поступают, через одну.
О, способ определить запущены ли мы с админ правами. Спасибо.

Уже хотел было спросить: как в драйвера теперь подписываете… А тут...

Вообще я очень удивлен
По драйвером я понимаю sys-файлы, которые имплементируют работу с каким-либо устройством
А здесь в статье речь про OpenAL.
Налицо — смешение понятий и их неконсистентное использование.
Ещё присоединюсь к оратору выше: в моих разработках хватало наличия разделяемых библиотек в каталоге приложения и их было необязательно закидывать в системный каталог (более того: это является плохим паттернов)
Зачем так сложно (CreateFile/GetFileInformationByHandleEx/HeapAlloc/ReadFile/WriteFile/HeapFree/CloseHandle), да ещё без обработки всех возможных ошибок, когда есть CopyFile?
Код выдран из контекста. Это не есть туториал, а, скорее, краткая выжимка.

В заголовке опечатка, д.б. "0xc00007b", HEX-код ошибки же.


2gecube
Есть ещё "User Mode" драйвера, выглядят обычными dll.
Например, драйвер на звуковую карту стоит от производителя, а звук хочется выводить по-своему, используя, например, системный API или сторонний движок.

Да, я понимаю, реальность опять отличается от моих ожиданий… Но автор мог хотя бы сгладить это впечатление сразу разъяснив про что идёт речь.
Sign up to leave a comment.

Articles