@Linda-chan

Тег программизм в блоге Linda-chan

Linda-chan

Разбираюсь со счётчиками производительности Windows. При чём самым хардкорным методом, без дотнет обёрток, без DPH.DLL, а прямо через реестр с парсингом двоичных данных. И это пипец, надо сказать ^^'
Пробовала спрашивать нейросети, но те либо откровенную дичь несут, либо всё к тем же обёрткам отсылают. Один запрос вообще выдал мне некий скелет, куда нейросеть предложила самостоятельно дописать код, который меня и интересовал.
Поэтому пришлось читать и страдать. Страдать в основном потому, что там нет шортката, быстрого кода, который можно написать для решения конкретной задачи и не разбираться со всем остальным. Разбираться таки придётся ^^'

Linda-chan

В заголовочнике winperf.h обнаружились константы:
• PERF_DETAIL_NOVICE
• PERF_DETAIL_ADVANCED
• PERF_DETAIL_EXPERT
• PERF_DETAIL_WIZARD

Linda-chan

Кстати о переполнении. Если просто приплюсовать к переменной единичку и словить ошибку переполнения, у переменной останется тоже самое значение. Тоесть это только в цикле старший бит переворачивается.

Linda-chan

Поняла, в чём проблема. Если цикл идёт от 1 до 3, то на выходе из него переменная будет равна 4. Никогда раньше не использовала переменную из цикла после выхода из него, так что не задумывалась об этом. Судя по документации, в конце итерации значение переменной плюсуется, после чего проверяется: если переменная меньше или равна конечному значению, то выполняется следующая итерация, иначе – выход. Тоесть, условием выхода является превышение конечного значения, а, если конечное значение – самое большое для данного типа переменной, то происходит переполнение. Ну и самое большое значение Long – 0x7FFFFFFF, а самое маленькое – 0x80000000, так что понятно, почему у меня переменная как бы перескакивала к началу цикла.

Linda-chan

Столкнулась с неожиданной проблемой.
Есть тип данных Long, который принимает значения от -2'147'483'648 до 2'147'483'647. Если взять пустой цикл от меньшего к большему, то оно сначала пробегает все значения, а потом случается ошибка 6 – «Overflow». Значение переменной из цикла в этот момент равняется -2'147'483'648.
Что характерно, в VBA та же история.
Ещё интересно, что, если вписать значение -2'147'483'648 в редакторе кода, то он автоматом в конце впишет «#», тоесть укажет, что это значение типа Double. Если подставить «&», тоесть, что это Long, то редактор начнёт выдавать ошибку «Expected: expression». А вот с -2'147'483'647 уже всё в порядке.
Наверняка, не связано, но всё равно забавно.

Linda-chan

Ещё с нулевых у меня был код на VC++, который форматировал Double в удобочитаемый вид. Сначала он делает так:

sprintf(TXT, "%lf", dblByaka);

На выходе получается что-то в духе «123.456789», а потом TXT пизается в GetNumberFormat(), который уже форматирует этот текст в то, что задано в региональных настройках (или что укажешь в специальной структуре).
Недавно вдруг обнаружилось, что в Windows 2000 и ниже этот код возвращает пустую строку при очень маленьких значениях dblByaka. Начала разбираться и выяснила, что sprintf() выдаёт мне «0,000000123» вместо «0.000000123». Тоесть именно в этом случае он ставит запятую вместо точки, как это происходит во всех остальных случаях. А вот в Windows XP и выше такого не наблюдается. Мистика.

Linda-chan

Требую Бейсикпанк – жанр и мир, в котором все программы написаны на тех или иных диалектах Бейсика!

Linda-chan

Dollars that make your program run faster

https://www.aivosto.com/articles/stringopt.html
Речь про «Mid$() vs Mid()», а не то, что вы подумали.

Linda-chan

Попутно выяснила занятное. У функции DeviceIOControl(), которая позволяет давать команды устройствам и получать от них всякие данные (как раз через неё пишутся и читаются данные reparse point), есть такие параметры: входной буфер с размером, выходной буфер с размером, сколько было записано в выходной буфер, ну и ссылка на OVERLAPPED для асинхронной операции. Буферы опциональны в зависимости от устройства и команды, параметр, возвращающий количество записанного, – тоже, ну и OVERLAPPED. Ну, у меня при записи в reparse point операция синхронная и используется только входной буфер, поэтому в функцию передаю только входной буфер и его размер, а всё остальное – NULL. Ну и программа в результате вылетает. Оказалось, что, если параметр, принимающий OVERLAPPED, установлен в NULL, то параметр, принимающий количество записанного в выходной буфер, должен ссылаться на актуальную переменную, даже если выходной буфер – тоже NULL. Оказывается, Microsoft не только не добавила проверку этого параметра, но и использовала его значение где-то внутрях функции, о чём указала в документации. В общем, не делайте так =_=

Linda-chan

Короче, написала я прототип программы, которая данные хранит в reparse point. И оно работает: появляется файл длиной ноль байт, который, поскольку система не знает, что это такое, можно только удалить. Написать код, который вытащит эти данные, разумеется, – задача тривиальная, тоесть для маскировки подходит мало, но тут именно что нужно писать код или искать очень специальную утилиту, ибо никакими блокнотами такие файлы не открываются.

Linda-chan

А вот интересно... Можно ли сделать кастомную reparse point так, чтобы хранить в ней какие-то свои данные, не связанные с файловой системой? Типа как маскировка данных в файловых потоках, только ещё круче, что прямо код надо писать, чтобы вытащить эти данные.
// Возможно, этот пост содержит часть ответа на вопрос из предыдущего.

Linda-chan

Написала код, который изучает симлинк (на самом деле – reparse point) и выдаёт то, на что симлинк ссылается. Проверила – работает. Почти приступила к применению, но тут заметила, что в некоторых случаях код работает неправильно, выдаёт странные результаты. Начала изучать двоичные данные, которые парсит программа, и поняла, что что-то с ними не так: одни поля налезают на другие, хотя в других случаях всё с полями нормально. Начала копаться в MSDN. Оказалось, что документация про всему этому есть, но какая-то туманная, везде недосказанность, функций всего ничего, объясняются только общие концепции. Продолжила копать и повторно открыла для себя раздел «Open Specifications», в котором предельно чётко описаны все структуры, которые в этих самых reparse points используются. И оказалось, что в MSDN была описана одна структура, а в реальности используются другие структуры, по одной на каждый тип симлинков. А та, что описана в MSDN – вообще для сторонних реализаций. В итоге код придётся переписывать и снова всё тестировать. Но я всё равно не понимаю, чего Microsoft так тряслись над этими reparse points так, словно это пентагоновский секрет?

Linda-chan

Почему структура GUID не соответствует текстовому виду этого самого GUID?

Linda-chan

Узнала, что JavaScript поддерживает запись двоичных чисел как «0b10101010». В смысле, в принципе поддерживает двоичные числа.

Linda-chan

Не, я знаю, что For Each, не смотря на использование варианта, работает быстрее, чем просто For с индексом, но чтобы настолько... Коллекция, 240 тысяч элементов типа Long, с которым в цикле производятся действия (коллекция перегоняется в массив). For с индексом пережёвывает коллекцию за тридцать-сорок секунд. For Each проносится по коллекции за 0.12 секунд.

Linda-chan

Научилась делать ботов-уведомляторов для телеграмки на VB. Документация по API, конечно, написана в лучших традициях Роберта Гейла. Особенно порадовало описание отправки картинок и файлов на сервер, типа, можно указать URL, можно указать ID, а можно «КАК БРОУЗЕР ЗАГРУЖАЕТ КАРТИНКИ НА САЙТ». Я час ломала голову, пока не додумалась, что оно в отправляемой форме хочет имя файла, даже если это имя потом нигде не будет использоваться.

Linda-chan

Я тут пишу кое-что, и снова столкнулась с такими мерзкими, но неизбежными вещами, как байтовые буферы, в том числе запихнутые в строки. Всвязи с чем два наблюдения.
1. У VB нет встроенных механизмов, чтобы скопировать часть одного байтового буфера в другой. CopyMemory().
2. Строки в VB – юникодные, но могут быть ANSI, если хорошо попросить. Понять, в каком формате строка, очень трудно, но сам VB знает, что там внутри.

Linda-chan

Разбирая старые завалы неожиданно поняла, что некоторые библиотеки, которые у меня, вроде как, актуальны, я написала в 2005 году. Например, библиотека для субклассинга окон, которую я использую то тут, то там, была скомпилирована 10.10.2005 и с тех пор не менялась.

Linda-chan

В Windows можно выбрать локаль для пользователя, и от неё будет форматироваться всякое вроде чисел и дат. А чтобы форматировать оные числа и даты, есть ряд функций вроде GetNumberFormat() и GetDateFormat(). Они позволяют отформатировать что-то, используя собственную маску, используя системную маску или то, чем системную маску переопределил пользователь в региональных настройках. Конкретно дата-время форматируются двумя разными функциями, которые выполняют свою работу хорошо, но всё же один нюанс остаётся за кадром: порядок следования. Ну, тоесть, я с детства знаю, что сначала идёт дата, а потом время: возможно, в школе так научили. Но вот есть программы вроде Notepad2, которые сначала вставляют время, а потом – дату. И в локали нет ничего на эту тему, только отдельный формат даты и отдельный формат времени. И как быть? Вообще, есть какие-то правила на сей счёт?

Linda-chan

Два часа билась над алгоритмом перевода химетриков в пиксели через миллиметры и дюймы. Пришлось даже писать для себя мини-гайд о сути операции деления. Совсем плохо стало у меня с математикой. Последствия коронки?

Добавить пост

Вы можете выбрать до 10 файлов общим размером не более 10 МБ.
Для форматирования текста используется Markdown.