| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Не работает декремент и xor |
| Автор: StillPhelix 27.1.2016, 19:46 | ||
Не работает декремент и xor. Коппилируется нормально. Не ребочие строки откоментированны. Исходник ниже.
|
| Автор: StillPhelix 27.1.2016, 20:39 | ||
|
| Автор: StillPhelix 28.1.2016, 01:14 | ||
прямая цитата из MSDN: PHKEY Pointer to an HKEY. This type is declared in WinDef.h as follows: typedef HANDLE *PHANDLE; Нет. Прямая цитата из MSDN: inline LSTATUS CAtlTransactionManager::RegCreateKeyEx( HKEY hKey, LPCTSTR lpSubKey, DWORD dwReserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ); Проблема уже решена; смотри мой второй пост. Компилятор - visual studio 2010. Это чистый C++. Ваши правки подойдут только для MFC C++ и в этом случае не канают. |
| Автор: feodorv 28.1.2016, 03:59 | ||||||
Это я понял.
Это глупость. Дело, конечно, Ваше, но когда программа рухнет, не жалуйтесь. PS Вы бы хоть https://msdn.microsoft.com/en-us/library/windows/desktop/aa446595%28v=vs.85%29.aspx посмотрели, что ли.
Вызов RegCreateKeyEx заносит результат по адресу phkResult, то есть по этому адресу обязана располагаться доступная память. https://msdn.microsoft.com/en-us/library/windows/desktop/ms724844%28v=vs.85%29.aspx:
|
| Автор: StillPhelix 28.1.2016, 12:04 |
MFC C++ не вызавает API. Вместо этого она обращается к библиотеке MFC, а та в свою очередь вызывает этот API. Чистый C++ вызывает API на прямую. Если не верите, то дизассемблируйте две программы, с соответствующими вызовами (на С++ и MFC C++). Все проекты MFC в 2 раза больше по размеру, чем проекты С++. И в visual studio они создаються разными путями. Переменная, содержащая адрес (hKey) и сам адрес - это две разные вещи. Поэтому, *hKey даст функции значение самой переменной, адрес которой храниться в hKey. Что и нужно данной API. Такой её прототип. Если вас интересует как работать с указателями, то прочитайте об этом, например в этой книге : Харви М. Дейтел, Пол Дж. Дейтел Как программировать на C++ (2008). Вобщем, &res - это адрес. А hKey, переменная, содержащая адрес. Поэтому программа не рухнет. С точки зрения С++ и компилятора С++ она написана правильно. |
| Автор: baldman88 28.1.2016, 14:53 |
| Раз уж Вы так рьяно рассказываете про С++ и советуете читать книги (при этом не самые удачные, ИМХО), то feodorv Вас совершенно правильно ткнул носом в тот факт, что указатель hKey у Вас есть, но вот на что он указывает никому не известно. По стандарту С++ указатели не инициализируются значениями по умолчанию. Таким образом, в один "прекрасный" момент, ваш hKey будет указывать на какой-нибудь участок памяти, который, при записи в него из Вашей программы, сможет вызвать серьезную ошибку в работе ОС. Так что прежде чем грубить, попытайтесь понять, что до Вас хотят донести |
| Автор: xvr 28.1.2016, 14:58 |
| 2 ТС - очень рекомендуется почитать буквари (можно те, что сами тут и упоминули) прежде чем нести ахинею прикрываясь красивыми словами про MFC/API/C++/прототипы |
| Автор: StillPhelix 28.1.2016, 16:35 | ||
| baldman88, xvr,
В этой строке инициализируется дескриптор. |
| Автор: xvr 28.1.2016, 18:00 | ||||||
В этой строке вызов RegCreateKeyEx запишет по указателю hKey ваш дескриптор. Так как этот указатель никто не инициализировал, то и попадет он неизвестно куда. Вам повезло, что там оказалась память и она ни с кем не пересеклась. Напишите в строке 13 ( PHKEY hKey;) так -
|
| Автор: StillPhelix 28.1.2016, 19:36 | ||||||||
это значит, что компилятор выделяет переменной hKey память и адрес. А код
её и так инициализирует. Адрес-то этой переменной функции известен. Памать под переменную выделена. Поэтому обнулять эту переменную смысла никакого нет. Это же не счётчик. Современный оптимизирующий копилятор из кода
= NULL скорее всего выбросит. Я эту программу прогонял не только через отладчик (visual studio и winDbg), но и дизассемблер. Код полностью работоспособен. Можете проверить сами. |
| Автор: baldman88 28.1.2016, 19:53 | ||
Я только сейчас понял, что эта функция делает. Видимо внутри она делает что-то вроде:
Мда. Такое уродливое API еще поискать нужно. Надеюсь никогда не доведется с ним иметь дело. |
| Автор: StillPhelix 28.1.2016, 21:05 |
| Если коротко, то в SDK от Microsoft, сказано следующее. RegCreateKeyEx передаёт адрес дескриптора созданного ключа в переменную, адрес которой храниться в указателе типа PHKEY ( это hKey). А PHKEY, в свою очередь, указывает на HKEY. RegQueryValueEx, RegSetValueEx и RegSetValueEx требуют значение дескриптора. Сам дескриптор - показывает на нужный объект. Для этого указатель hKey нужно разыменовать. Поэтому пишем: *hKey. |
| Автор: feodorv 28.1.2016, 22:13 | ||||||||
В логике Вам не окажешь. Осталось только понять, где именно в коде
Современный компилятор на подобные конструкции выдаёт предупреждение об использовании переменной hKey без инициализации. У Вас такое предупреждение есть? Добавлено через 2 минуты и 9 секунд Зря Вы так. Тогда и fopen тоже уродлив. Что же не уродливо? |
| Автор: baldman88 29.1.2016, 00:16 | ||
Про fopen не соглашусь, там все интуитивно понятно. Передаем имя файла и режим в котором хотим открыть файл. В случае успеха получаем адрес, а в случае неудачи -- NULL. Здесь же 100500 параметров, да еще и непонятно что передавать. То ли нужно передать указатель на уже выделенную память, то ли просто указатель, в который будет занесен адрес памяти, которая будет выделена в функции. |
| Автор: volatile 29.1.2016, 01:08 | ||||
маразм крепчал если это так, то как ваша программа получит этот указатель-то ??? там что, по вашему, ссылка на указатель в аргументах ??? господа baldman88, StillPhelix, вам срочно учить что такое указатель, что такое функция, как передаются и возвращаются параметры функции, а уж потом пытаться лезть в API, и высказывать о ней какие-то критические замечания. |
| Автор: feodorv 29.1.2016, 03:38 | ||||||||||
И Вы туда же. Вызов сишной функции (то есть без привлечения си-плюс-плюсных ссылок) не способен изменить значение передаваемого ей аргумента, если Вы не передавали ей заодно и его адрес. Поэтому hKey каким был до вызова RegCreateKeyEx, таким и остался после. Мусорным, неинициализированным. Но чтобы по адресу, на который указывает hKey, можно было хоть что-то занести, hKey должен указывать на доступную память. Это можно сделать так:
|
| Автор: baldman88 29.1.2016, 09:04 | ||||
Посыпаю голову пеплом. Посмотрел объявление этой функции и увидел, что параметр передается не по ссылке. |
| Автор: xvr 29.1.2016, 14:38 | ||||
Ну раз уж вы словам не верите, то проверил. Вот ваш код, обрезанный до минимума:
Вот результат запуска -
Как вы это объясните, великий теоретик вы наш? |
| Автор: StillPhelix 13.2.2016, 19:59 |
| feodorv, ответы на все ваши вопросы, в библиотеке MSDN или Microsoft Visual Studio Documentation. В частности, ссылка для RegCreateKeyEx в MSDN : https://msdn.microsoft.com/en-us/library/windows/desktop/ms724844%28v=vs.85%29.aspx. По всем остальные вопросы - тудаже. В конце каждой темы есть ссылка на MSDN. Программа в Microsoft Visual Studio компилируется и работает нормально. Правки, небходимые для нормальной работы во втором посту сверху. |
| Автор: feodorv 14.2.2016, 05:29 | ||
При чем здесь MSDN? Отправлять в функцию неинициализированный указатель - это выстрел в ногу. Сейчас Вам повезло, а потом не повезёт. И я уже писал, что это дело Ваше, раз Ваше упрямство превышает все разумные пределы.
|