Вверх ↑
Ответов: 9906
Рейтинг: 351
#1: 2016-04-05 00:22:18 ЛС | профиль | цитата
Все, nesco -- разобрался блин. И сделал маленькое открытие, упрощающее наши коды.

1) Почему не падает @fn[1].
Вообще-то, это тип pchar, который, для пустой строки fn - тупо равен нулю (проверил отладочными выводами). Если им пользоваться как указателем на символ - упадет сразу. В твоем коде это передается в _hi_onEvent, а Дельфи сначала переводит это дело в строку с помощью LStrFromPChar. А там есть "страховочка" против нулевого указателя. Она возвращает пустую строку. Потому и не падает.
В ком еще есть "страховочка", а в ком ее нет -- тайна сия велика есть.

2) Почему падает CharLower.
Потому что мягкотелые - говнюки. Оказывается, привести к нижнему регистру пустую строку - неразрешимая задача. Это мой прокол, ибо такой гадости я от них не ожидал.
НО, они подстелили соломку для лохов. Если указатель на строку "почти нулевой" (hword=0), то они считают его не указателем, а символом, который приводят к нижнему регистру и его и возвращают. Т.е., если ты лоханулся, и влепил нулевой указатель, то они посчитают его нулевым символом, приведут его к нижнему регистру, и ноль же и вернут.
Неправильными действиями получаем правильный результат, потому что кто-то специально рассчитал, что ты будешь действовать неправильно.
Дурдом на каникулах, но я в этом не виноват.

3) Маленькое открытие.
Дельфи, в тот момент, когда ты где-то запомнил указатель на символ строки, начинает подозревать тебя в том, что ты будешь менять содержимое строки, и АВТОМАТИЧЕСКИ выполняет UniqueString, без нашего участия. Если и мы это делаем, то это делается два раза (буквально подряд).
Вот такой он парень, этот Дельфи. Если мы получаем указатель на символы с помощью PChar(fn) -- то он нас ни в чем плохом не подозревает. А если тот же самый указатель с помощью @fn[1] -- сразу же влепляет UniqueString.

4) Вывод.
Надо делать CharLower(@st[1]) с последующим автоматическим преобразованием его в string, и забыть про UniqueString (он сам про него вспомнит).
Обновил этот аттач по вышеуказанным причинам.


------------ Дoбавленo в 00.22:
nesco писал(а):
То-то она нагарантировала
Ну а я-то тут причем. Вот ее код из system.pas (если убрать условную компиляцию, для понятности)
#pas
function _LStrToPChar(const s: AnsiString): PChar;
asm
{ -> EAX pointer to str }
{ <- EAX pointer to PChar }

TEST EAX,EAX
JE @@handle0
RET
@@zeroByte:
DB 0
@@handle0:
MOV EAX,offset @@zeroByte
end;
Вот то тебе и весь сказ
карма: 9

1
Голосовали:flint2