![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
aktuba |
|
||||
![]() Смышленный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1915 Регистрация: 24.4.2006 Где: Планета Земля Репутация: 16 Всего: 38 |
Не так давно я описывал одну проблему, возникшую в одном из проектов. Сегодня вот нашел немного инфы на эту тему, точнее на тему использования WideString в DLL. Думаю, это многим пригодится, т.к. ни в одной книге, ни на других форумах подобного не встречал.
Итак, вкратце: при использовании WideString НЕ НАДО никакого выделения памяти под строки, НЕ НАДО подключать никакие доп. модули и т.д. В общем не надо НИЧЕГО!!! Не верите? Попробуйте: Код DLL:
Код программы:
Все. Компилируем и проверяем. Странно... Работает ![]() Теперь небольшое объяснение. Все прекрасно знают, что в EXE и в DLL менеджеры памяти разные и именно из-за этого и возникают проблемы при передаче строк из программы в dll и обратно. Но, при использовании WideString, используется не обычный менеджер памяти, а специальный - системный. Специальный менеджер сделан для совместимости с COM. И этот менеджер памяти используется один на всех, поэтому WideString можно безопасно передавать и без использования ShareMem, FastShareMem и т.д. - просто в этом случае вы будете терять время на перекодировку в Unicode и обратно. Теперь по поводу выделения/освобождения памяти под WideString. При работе с WideString используются функции SysAllocString/SysReallocString/SysFreeString, которые можно вызвать явно или, как делает Delphi, неявно. Плюс к этому, в отличии от AnsiString, где для определения момента освобождения памяти, занимаемой строкой, используется механизм подсчета ссылок, в WideString всегда используется явно. Т.е. при присваивании wstr1 := wstr2, для AnsiString это будет просто копирование указателя, а для WideString создание новой строки и копирование содержимого wstr2 в созданную строку. Думаю, это многим поможет... -------------------- ![]() |
||||
|
|||||
Alexeis |
|
||||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Мне кажется ты ошибаешся. Посмотрим реализацию следующего кода.
Смотрим, что же у нас выходит в ассемблере
Вызов WStrLAsg пустой переход к _LStrLAsg Смотрим теперь на паскалевский вариант _LStrLAsg
Что же мы видим? Увеличение счетчика ссылок на строку и копирование указателя на строку. Нет ни какого копирования содержимого строки. Просто ссылка и все. Причем используется стандарный менеджер памяти. В справку написано использовать модуль ShareMem при работе с длинными строками WideString тоже относится к длинным строкам. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||||
|
|||||||
Quadr0 |
|
|||
Unregistered |
...
Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 13:46 |
|||
|
||||
aktuba |
|
||||||||
![]() Смышленный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1915 Регистрация: 24.4.2006 Где: Планета Земля Репутация: 16 Всего: 38 |
Да нет, мне кажется ты немного заблуждаешься. Или Delphi умнее, чем мы думаем и использует то, что необходимо в данной ситуации =). Для примера:
В отличии от твоего кода - я использую русский текст. Вот что дает дебагер: ![]() Здесь видно, что не только адреса ссылок на переменные разные, но и адрес нахождения самих данных различается. Но, пойдем дальше...
Снова не верно. Смотрим скрин: ![]() Снова видим, что никакого перехода к _LStrLAsg нет в природе. Все на уровне работы с WideString, ну и соответственно, используется SysRealloc, как я и написал в начале.
Снова повторю - неверно. Для WideString используется системный менеджер памяти, что наглядно видно из скринов. Правда есть подозрение, что в предыдущих версиях Delphi используется стандартный... Я же говорю про BDS2006/TurboDelphi... P.S.: пока писал - Quadr0 откоментил, но думаю скрины и пояснения многим помогут... Это сообщение отредактировал(а) aktuba - 26.2.2007, 12:32 -------------------- ![]() |
||||||||
|
|||||||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Все тестил на Delphi7. Там используется именно _LStrLAsg. В любом случае использование недокументированых возможностей сопрежено с большими проблемами совместимости версии. Раз в документации этого нет, значит Borland не обязяна сохранять эту систему в будущем. Непойму чем так усложняет жизнь простое указание модуля FastShareMem? -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
aktuba |
|
||||||
![]() Смышленный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1915 Регистрация: 24.4.2006 Где: Планета Земля Репутация: 16 Всего: 38 |
Сейчас посмотрел на Delphi 7, там используется тоже самое, что и на BDS, т.е. к _LStrLAsg перехода нет. К сожалению не могу выложить скрин, т.к. D7 установлен на ноуте без инета...
Вот выдержка из хелпа D7:
-------------------- ![]() |
||||||
|
|||||||
Alexeis |
|
||||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Упс не догядел. Это был фрагмент линуксового кода
![]() Да уж и в семерке
p1 и p2 указывают на разные области памяти, тогда как
Указывают на одну. Добавлено @ 13:31 Да пожалуй основываясь на
Можно смело не использовать ни каких FastshareMem. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||||
|
|||||||
aktuba |
|
|||
![]() Смышленный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1915 Регистрация: 24.4.2006 Где: Планета Земля Репутация: 16 Всего: 38 |
Alexeis, не хочется снова указывать ошибку, а приходится =((( - во втором коде замени AnsiString на WideString и все встанет на места. p1 и p2 будут указывать на разные области памяти....
-------------------- ![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Тогда еще небольшое дополнение к
Функция SysReAllocStringLen вообще виндовая и не принадлежит самому приложению. Память выделяется и уничтожается внешним, как для DLL так и для программы, менеджером памяти.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
В связи с этим хочется развеять еще один скользкий вопрос. Считается, что использование Pchar вместо AnsiString позволяет также избавиться от проблем с менеджером памяти. Однако часто можно увидеть ситуацию, когда память для Pchar выделяется при помощи GetMem или New. Такой ход является очень опасным и допустим, только в случае если память выделенная GetMem освобождается в том же модуле, что и была выделена иначе нужно использовать HeapAlloc, GlobalAlloc.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeyt |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 332 Регистрация: 15.9.2006 Где: около Москвы Репутация: нет Всего: 2 |
aktuba,
Alexeis, Спасибо за информацию. Очень полезно (у меня есть кое-какие DLL). |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 62 Всего: 128 |
-------------------- There are always someone smarter than you... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |