Вверх ↑
Ответов: 4655
Рейтинг: 760
#1: 2025-02-16 18:25:15 ЛС | профиль | цитата
Тип String в Delphi является предметом автоматического освобождения выделенной памяти при выходе переменной из области видимости.
Реализуется это с помощью счетчика ссылок.
Присвоили переменной, передали параметром в функцию - счетчик увеличился.
Присвоили переменной другое значение или вышли из функции - счетчик уменьшился.
Счетчик стал равен 0 - освобождаем выделенную память.

Это является источником проблем при использовании DLL: приложение и DLL являются независимыми исполняемыми файлами, может даже скомпилированными разными компиляторами. Соответственно, в каждом из них код самостоятельно выделяет память и освобождает. Конкретнее - существует менеджер памяти, который отвечает за это.

Когда мы передаём string из главного модуля в функцию DLL мы выделили память под неё в главном модуле.
Но, поскольку DLL сделана на Delphi и работает со string как описано выше, вполне возможна ситуация, когда код DLL попытается освободить память, выделенную под string, которая пришла ему в функцию в качестве параметра.
Но освобождать он будет с помощью своего менеджера памяти, поскольку ничего не знает о каких-либо других.
А менеджер памяти не имеет в своем списке тот блок памяти, в котором находится данная строка.
Вот в этом месте возникает ошибка.
Аналогично если строка создаётся в DLL и возвращается наверх в результатах вызова своей функции.

Решается это подменой менеджера памяти в DLL на тот, что в основном модуле. Я не знаю, предусмотрено ли такое при создании DLL в HiAsm.

В данном случае доступ к символам строки по индексу _data.sdata[1] приводит к копированию строки. Следовательно, предыдущая строка, вероятно, уничтожается, что и приводит к ошибке.
pchar(_data.sdata) конструирует новую строку в своём менеджере, копируя исходную строку, но не уничтожая её. Возможно, так и обходили проблему общего менеджера памяти - создавали копию строки.

И да, на FPC ошибки нет, возможно, потому что там нет копирования строки при _data.sdata[1] (особенности реализации компиляторов).
Поскольку FPC как бы основной компилятор, на нём протестировали и забыли. А на Delphi вылезло.
карма: 26

2
Голосовали:tom-it, envoy_sky
Редактировалось 3 раз(а), последний 2025-02-16 18:35:47