вторник, 1 марта 2016 г.

Раннее исполнение кода в Delphi приложениях

Как вы думаете, сколько кода выполняется до того момента, как приложение запустится, или отладчик передаст управление в ваши руки?

Много - поверьте мне.
Вы даже чихнуть не успеете, как окажется, что кто-то уже успел поработать в теле вашего процесса и отдал его вам на руки в момент его запуска - работайте и удивляйтесь.

Нет, не вирусы, зачем? Вполне легальные продукты, контролирующие все и вся.

Думаете - вру и считаете что при нажатии кнопки F7 (Trace Into) вы полностью контролируете процесс отладки?
Тогда я вас разочарую, есть множество способов выполнить код, до того момента, как вы приступили к его дебагу.

О нескольких я попробую рассказать.

среда, 29 апреля 2015 г.

Анализ задачи №18 от Александра Алексеева (ака GunSmoker)

Кажется я первый раз попал в тупик.
Не то, чтобы я сильно умный, но и задачка — не "Балтика 9".

Первая часть задачи выглядела вот так:

Что не так с этим кодом?

procedure TForm1.Button1Click(Sender: TObject);
var
  Wnd: HWND;
 
  function EnumWindowsProc(const AWnd: HWND; const AParam: LPARAM): BOOL; stdcall;
  begin
    if AWnd = Wnd then
      Caption := 'OK';
    Result := True;
  end;
 
begin
  Wnd := Handle;
  EnumWindows(@EnumWindowsProc, 0);
end;

Приступим.

пятница, 10 апреля 2015 г.

Чем меня порадовала ХЕ8

В последнее время я все чаще задумываюсь о смысле апдейта текущей версии Delphi на более новую. Есть ли в этом необходимость?
С учетом, что я разрабатываю 32 битные приложения только под Win - вся эта петрушка в виде возможности разработки под Андроид или iOS прямо на Delphi, ну... скажем так — не сильно востребована.
А вот что более востребовано — так это стабильная работа среды, отсутствие ошибок при работе с дженериками/лямдами и всем тем "синтаксическим сахаром", который внедряется уже какой год.
Вы будете смеяться, но я однажды вообще от инлайнов отказался по многим причинам, в частности одна из них была в том, что кодогенератор выдавал абсолютно невалидный асм код в определенных ситуациях, абсолютно переиначивая всю логику работы inline функции (банально не тот результат возвращала). Кажется это было на 2010 или ХЕ первой.

Впрочем посмотрим что мы имеем сейчас.

вторник, 31 марта 2015 г.

Работаем с Compound File

С составными файлами я работаю давно, больше 15 лет. За все время работы у меня накопилось достаточно информации о плюсах и минусах составных файлов.
С одной стороны они являются действительно очень удобным хранилищем информации, позволяющим менять данные на лету, с другой стороны это удобство частично нивелируется скоростью доступа к данным.
Вообще для чего обычно используют составные файлы?
Для всего, что нужно хранить в некоем контейнере.
К примеру, файлы старых версий Microsoft Office от 97 до 2003 включительно (состоящие на самом деле из нескольких десятков файлов), хранились как раз в составном файле. Сейчас тоже хранятся, только в качестве контейнера используется ZIP.

Инсталляционные пакеты MSI тоже являются составными файлами, и даже файл кэша эскизов папок Thumbs.db использует этот формат.

Правда для того же Word есть целый комплекс утилит (Recovery for Word, Word Recovery Toolbox, Munsoft Easy Word Recovery) восстанавливающих, ну или по крайней мере пытающихся восстановить, поврежденные документы. Выводы можете сделать сами.
Хотя, при должной работе с составными файлами проблему их повреждения можно решить (и я покажу как).

Ну и, конечно же, несомненным плюсом этого формата является то, что внутри хранилища эмулируется полноценная файловая система со своими файлами и папками.

Кстати, нюанс. Перед началом статьи я провел опрос на нескольких форумах, и выяснилось, что подавляющее большинство разработчиков не работают с составными файлами, причем по простой причине — не слышали что это такое.
Вот сейчас и закроем этот пробел.

воскресенье, 22 февраля 2015 г.

Работаем с "заданиями" (Job)

Буквально на неделе на форуме появились два интересных вопроса, ответ на которые был очевиден, но... Программист, как вы знаете, существо с очень пытливым мозгом, он любит различные эксперименты, не смотря на то, что ответ на задачу мог быть уже озвучен :)

Впрочем, давайте посмотрим на первый вопрос:
Запускаю в отдельном потоке некий процесс (не мой, переделывать его не имею возможности), который необходимо завершить вместе с завершением основной (моей) программы.Если моя программа завершается штатно - то ничего сложного нет. Но если не штатно (пользователь убил через диспетчер задач) - так как быть тут?
В голову пока приходит только CreateRemoteThread+LoadLibrary+моя dll, которая будет следить за основным процессом.Подскажите более изящные решения.
Попробуем подсказать...

пятница, 2 января 2015 г.

Ответ на предновогоднюю задачку

Если вы вдруг заинтересовались самой задачей, и работаете над ее решением, то вам лучше не читать данный пост, так как в нем я по шагам опишу все проблемы, которые должен решить программист с полным описанием подхода.

Задача действительно интересная.
На данный момент мне прислали два её решения, причем у каждого оказался свой индивидуальный подход.

Примерное время на решение, около 3-4 часов (один вечер).
Именно столько было затрачено каждым из решивших задачу программистов, включая меня.

Ну и ответ на введенное максимальное пороговое число (10 в 12 степени) будет: $259814D6C9AAF914221E (это вам для самопроверки).

Пора перейти к самой сути.


четверг, 25 декабря 2014 г.

Предновогодняя задачка для разминки мозга

Пришлось тут на днях решать для студента (первого курса) задачку.
Дословно выглядит вот так:
2014 ACM-ICPC China Hunan Invitational Programming Contest
There is a simple problem. Given a number N.
You are going to calculate N%1+ N%2+ N%3+...+ N%N.
Input: The length N(1<=N<=10^12).
Output: Answer.
Sample input 5
Sample output 4
Вроде ничего сложного, однако-ж результат суммирования по модулю явно не уложится ни в один из поддерживаемых типов (int64 максимум 8 байт).

Сразу уточню: задачка олимпиадная, причем свежего 14-го года :)