Приложение Delphi 2010 загружает DLL-библиотеку Delphi 7 - PullRequest
1 голос
/ 06 декабря 2011

Мое приложение скомпилировано с Delphi 2010. Это приложение загружает скомпилированную DLL Delphi 7, которая загружает скомпилированную DLL Delphi 2010.

D2010 app LOADS D7 DLL LOADS D2010 DLL

Экспортируемые функции DLL-библиотеки D7 используют Widestrings, а экспортируемые функции DLL-библиотеки Delphi 2010 используют strings.

Как мы все знаем, strings в Delphi 2010 - это Unicode (2 байта), а в Delphi 7 - Ansi (1 байт).

Все мои тесты показывают, что он работает, несмотря на то, что не должен. Мне интересно:

Почему это работает?

Что может пойти не так?

Какой диспетчер памяти следует использовать (DLL-библиотека диспетчера памяти Delphi 2010 или Delphi 7)

1 Ответ

7 голосов
/ 06 декабря 2011

В D2009 и D2010 RTL имеет логику (директива {$STRINGCHECKS ON} компилятора), которая позволяет AnsiString получать полезную нагрузку Unicode и UnicodeString получать полезную нагрузку Ansi через границы модуля, и затем выполнить тихое встроенное преобразование данных в правильный тип строки при доступе к данным AnsiString / UnicodeString. Это в первую очередь для поддержки устаревших проектов C ++, которые используют обработчики событий с параметрами AnsiString на стороне C ++ и переменными UnicodeString на стороне Delphi. В этом случае это также может позволить D7 DLL передавать данные Ansi в D2010 DLL (однако в XE была удалена директива STRINGCHECKS).

Однако я ожидаю, что DLL D2010 выйдет из строя, потому что структура памяти записи StrRec (которая предшествует символьным данным в памяти) изменилась в D2009, чтобы добавить поддержку кодовых страниц, поэтому библиотека D7 не будет выделяться совместимый с D2010 StrRec при передаче значения AnsiString параметру UnicodeString в DLL D2010. Я ожидаю, что DLL D2010 аварийно завершит работу, когда попытается получить доступ / освободить память, которая не существует.

Это еще один аргумент против прохождения типов String через границы DLL. Просто не делай этого никогда. Вместо этого используйте WideString или PAnsiChar / PWideChar.

...