Советы по Delphi

         

Глава 32-Битный указатель


Все указатели в Delphi 32-битные. Вот простой тест. Разместите следующий код в обработчике события нажатия кнопки, и вы получите интересующую вас информацию.

    ShowMessage( Format('Указатель имеет размер %d, или являются %d-битными', [sizeof(pointer),8*sizeof(pointer)]) );

Я думаю что вы путаете размер элемента данных с тем, как это может быть интерполировано на физический адрес. "Указатели" даже на старых 8086/8088 процессорах были 32-битные по величине; включали в себя 16-битный сегмент и 16-битное смещение, которые, наконец, объединились, чтобы создать 20-битный физический адрес; некоторые другие комбинации сегмента и смещения могли указывать на ту же самый адрес физической памяти, что приводило к необходимости "нормализации" указателей для некоторых целей.

Для 16-битного расширенного (Enhanced) режима Windows, указатели во всех Borland Pascal продуктах были интра-сегментированные (intra-segment), то есть, часть "сегмента" данного указателя должна всегда была работать с расширенным селектором памяти (extended memory selector); и затем учитывать следующее за ним 16-битное "смещение"; данная seg/ofs (сегмент/смещение) модель могла дать для структуры данных максимум 64kb. Windows содержит методы преодоления этого ограничения (например, использование процедуры _AHIncr), но это не происходит автоматически, как в случае с C-шной "Huge" (огромный) -директивой для данных. В этом случае 16-битная версия Delphi не имеет в своем арсенале "Huge"-указателей. 32-битная Delphi решает эту проблему.

Насколько я в курсе, код VCL позволяет читать более, чем 64k bitmap (для примера), используя (и хорошо это скрывая) системные клуджи (Windows kludges); посмотрите код VCL, и вы поймете, как это можно сделать в Delphi.

Да, но они 16:16 указатели, а не 16:32, которые вы, вероятно, хотели.

Господа, мы тут говорим о разных вещах. Если C DLL компилируются 16-битным компилятором, указатели в Delphi будут АБСОЛЮТНО совместимыми и 16:16-битными far- и huge- указателями в C (или C++). Проблем абсолютно никаких. Просто передавайте их...

С другой стороны, если приложение C (или C++) является Win32-приложением, оно пользуется только 32-битными смещениями. Сегменты (соответственно больше селекторов) невидимы и ведут отсчет от нулевого линейного базового адреса.

Обратите внимание, что речь идет о приложениях. Компоненты нулевого кольца (Ring 0) также используют 32-битные указатели, но в то же время изредка могут пользоваться и 48-битными. VXD - компоненты нулевого кольца.

Для вызова 16-битных приложений, вы просто делаете это. Ничего специально делать не нужно. Для вызова таких приложений из Win32-приложений, необходимо воспользоваться так называемыми "санками" (thunk). В таком случае не обойдешься простой заменой указателей, необходимо также сменить 16-битный стек на 32-битный. И много еще чего. Если ваша проблема только в этом, то поищите в Интернете файл CALL32NT.ZIP, он как раз этим и занимается. [001974]



Содержание раздела