Как более умный компилятор вызывает импортируемую функцию.


Перевод с блога The Old New Thing. Оригинал здесь.

Если функция объявлена с директивой dllimport, это указывает компилятору Visual Studio С/C++ на то, что данная функция является импортируемой, а не обычной внешней (external) функцией. Обладая этой дополнительной информацией, компилятор генерирует немного отличающийся код, когда ему необходимо обратиться к импортируемой функции, так как он в курсе особенностей импорта функций.

Во-первых, здесь больше нет необходимости в функции-заглушке, потому что компилятор может сгенерировать специальную команду call [__imp__FunctionName]. Далее, компилятор знает, что адрес импортируемой функции никогда не меняется и, следовательно, может оптимизировать множественные вызовы одной и той же функции:

mov   ebx, [__imp__FunctionName]

push  1

call  ebx      ; FunctionName(1)

push  2

call  ebx      ; FunctionName(2)

 

(Заметка для фанатиков: Эта оптимизация означает, что вы можете столкнуться с проблемами если будете модифицировать таблицу импорта во время работы программы, потому что для оптимизации указатель на функцию может быть загружен в регистр до того, как таблица импорта будет модифицирована. Смотрите на примере выше: вы изменили запись в таблице для __imp__FunctionName после выполнения mov ebx, [__imp__FunctionName] — ваши изменения не дадут эффекта, потому что старый адрес уже закеширован в регистре ebx.)

Подобным образом, если ваша программа пытается получить адрес импортируемой функции, которая была объявлена с директивой dllimport, компилятор распознает такую ситуацию и возвращает значение из таблицы адресов импортируемых функций.

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

Однако существует несколько ситуаций, когда необходимо создавать функции-заглушки. Мы рассмотрим их (и проблемы, возникающие с ними) в следующий раз.

Реклама
Запись опубликована в рубрике DLL. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s