четверг, 1 сентября 2011 г.

Экспортируемые функции, являющиеся forwarder-ами

Это перевод Exported functions that are really forwarders. Автор: Реймонд Чен.

В прошлый раз мы видели как экспортируемые функции в Win32 ведут себя похоже на экспорт функций в 16-битных Windows - только сместился акцент использования с импорта по номеру на импорт по имени. Этот акцент никак не выражен в формате исполняемого файла; и 16-битные и 32-битные DLL могут экспортировать функции по номеру и имени (и обоим одновременно).

Но в Win32 появляется новый тип экспортируемых функций, известный как forwarder.

Forwarder выглядит как обычная экспортируемая функция, за исключением того что запись в таблице экспорта по номерам говорит "Ох, на самом деле, я не функция в этой DLL. На самом деле - я функция вон в той DLL". К примеру, если вы сделаете
link /dump /exports kernel32.dll
То вы увидите что-то такое:

151   EnterCriticalSection (forwarded to NTDLL.RtlEnterCriticalSection)

Это означает, что если программа связана с KERNEL32.EnterCriticalSection, то загрузчик ОС молчаливо перенаправит функцию на NTDLL.RtlEnterCriticalSection. Forwarder-ы являются удобным способом сохранить внешний интерфейс, изменив функциональность выносом в отдельные DLL. Старая DLL продолжает экспортировать функцию, но сама функция была перемещена в новую DLL.

Трюк с forwarder - это лучше, чем иметь пустую функцию-заглушку в старой DLL, которая просто вызывает функцию в новой DLL: потому что функция заглушка создаёт зависимость между новой и старой DLL (в конце концов, старую DLL нужно связать с новой DLL, чтобы была возможность вызвать функцию!). А при использовании forwarder новая DLL не будет загружаться, если только кто-то не попросит перенаправленную функцию из старой DLL. В результате вы не платите за загрузку новой DLL пока кто-то её явно не попросит.

Okей, как мы увидели, с введением forwarder Win32 отошла от 16-битных Windows, но как только мы посмотрим на импорт, то увидим, что тут изменилось вообще всё. Мы посмотрим на эту историю в следующий раз.

2 комментария:

  1. Эх, еще бы знать, как в Delphi сделать именно такую функцию в DLL...

    ОтветитьУдалить
  2. > Эх, еще бы знать, как в Delphi сделать именно такую функцию в DLL

    Элементарно. Как я когда-то делал враппер. В interface описываете функцию как экспортируемую, а в implementation - как импортируемую. :)

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.