Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.08.2012, 22:28   #11
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Так, кажется, это не всем очевидно. Тогда поясню.

Нуль-терминированность строк в Delphi документирована и поэтому её использовать можно. Но не так, как это делаешь ты. Проблема в том, что ты указываешь функции буфер больше, чем у тебя есть.

Например, пусть в GetWindowCaption передали не валидный описатель (окно удалилось в аккурат в момент между получением описателя и вызовом GetWindowCaption для этого описателя). Тогда твой вариант первой строчкой установит длину результата в 0, т.е. Result будет равен nil.

Поскольку на ошибки ты не проверяшь, то будет выполняться вторая строчка. Тут проблема сидит ещё до вызова функции. С включенным range checking у тебя выбьет исключение при вычислении Result[1]. С выключенным range checking функция вызовется с указателем = nil и длинной = 1.

Это означает, что ты наврёшь функции (ты сказал, что у тебя есть 1 символ в буфере, а на самом деле буфера вообще нет). И если вдруг функция захочет обнулить буфер до начала всех работ, то ты схлопочешь Access Violation.

У моего варианта указанных проблем нет. Хотя обработку ошибок добавить не помешает.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 02.08.2012, 23:01   #12
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
У моего варианта указанных проблем нет. Хотя обработку ошибок добавить не помешает.
ну вообще тут правильно добавить проверку ошибок.
и бросать исключения.
минимум должна быть на ошибку и нулевой капш.

я любил этот код тем что он не изменяет длины строки в итоге.(если конечно кэпшн не стал короче)

Код:
function GetWindowCaption(Handle: HWND): String;
var len:integer;
begin
  SetLastError(0);
  SetLength(Result,0);
  len:=GetWindowTextLength(Handle);
  if GetLastError<>0 then //как там исключения бросать, забыл напрочь уже
  if len>0 then
   begin
    SetLength(Result,len);
    SetLength(Result,GetWindowText(Handle,@Result[1],Length(Result)+1));
   end;
end;
примерно так.

хотя, разве приведение к PChar не даст nil в случае пустой строки?(длина 0)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 02.08.2012, 23:49   #13
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
я любил этот код тем что он не изменяет длины строки в итоге
Да, это плюс, но поскольку в Delphi-программах используется менеджер памяти, то это не имеет большого значения. Изменения на -1 байт почти всегда просто приводят к изменению счётчика длины выделенной памяти, без перераспределения.

Цитата:
хотя, разве приведение к PChar не даст nil в случае пустой строки?(длина 0)
PChar никогда не даёт nil.

Код:
var 
  S: String;
  P: Pointer;
begin
  S := '';
  P := Pointer(S); // P = nil
  P := PChar(S); // P = @(#0)
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 03.08.2012, 00:10   #14
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
PChar никогда не даёт nil.
хм, ну тогда можно сделать так если что, тогда будет один байт буфера и будет все ок.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 03.08.2012, 17:10   #15
c0mp
 
Регистрация: 27.11.2011
Сообщений: 9
По умолчанию

Спасибо всем за развёрнутый ответ!
c0mp вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно возвращать созданный в функции объект? rpy3uH Общие вопросы C/C++ 4 10.11.2011 16:19
Не знаю как правильно сделать вызов функции Homutova_Julia Помощь студентам 14 07.06.2011 23:45
Как правильно вставить строки? Kostinok Microsoft Office Excel 6 28.05.2010 19:23
скрипт для приёма заказов на печать фото, через Интернет nickhop Фриланс 1 14.02.2010 18:11
как правильно прописать адрес в функции? (формула) coldis Microsoft Office Excel 3 18.02.2009 09:47