Что такое импорт
В предыдущем разделе я упомянул о модификаторе _declspec(dllimport). Импортируя идентификатор, необязательно прибегать к _declspec(dllimport) — можно использовать стандартное ключевое слово extern языка С. Но компилятор создаст чуть более эффективный код, если ему будет заранее известно, что идентификатор, на который мы ссылаемся, импортируется из LIB-файла DLL-модуля. Вот почемуя настоятельно рекомендую пользоваться ключевым словом _declpec(dllimport) для импортируемых функций и идентификаторов данных. Именно его подставляет зa Вас операционная система, когда Вы вызываете любую из стандартных Windows-функций.
Разрешая ссылки па импортируемые идентификаторы, компоновщик создает в конечном ЕХЕ-модуле раздел импорта (imports section). В нем перечисляются DLL, необходимые этому модулю, и идентификаторы, на которые есть ссылки из всех используемых DLL.
Воспользовавшись утилитой DumpBin.exe (с ключом -imports), мы можем увидеть содержимое раздела импорта. Ниже показан фрагмент полученной с ее помощью таблицы импорта Calc.exe.
C:\WINNT\SYSTEM32>DUMPBIN -imports Calc.EXE
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file calc.exe
File Type: EXECUTABLE IMAGE
Section contains the following imports:
SHELL32.dll
10010F4 Import Address Table
1012820 Import Name Table FFEFFFFF time datc stamp FFFFFFFF Index of first forwarder reference
77C42983 7A ShellAboutW
MSVCRT.dll
1001094 Import Address Table
10127C0 Import Name Table FFFFFFFF time date stamp FFFFFFFF Index of first forwarder reference
78010040 295 memmove
78018124 42 _EH_prolog
78014C34 2D1 toupper
78010F6E 2DD wcschr
78010668 2E3 wcslen
ADVAPI32.dll 1001000 Import Address Table 101272C Import Name Table FFFFFFFF time date stamp FFFFFFFF Index of first forwarder reference
779858F4 19A RegQueryValueExA
77985196 190 RegOpenKeyExA
77984BA1 178 RegCloseKey
KERNEL32.dll
1001010 Import Address Table
1012748 Import Name Table FFFFFFFF time date stamp FFFFFFFF Index of first forwarder reference
77ED4134 336 lstrcpyW
77ED33F8 1E5 LocalAlloc
77EDEE36 DB GetCommandLineW
77E01610 15E GetProfileIntW
77ED4BA4 1EC LocalReAlloc
Header contains the following hound import information. Bound to SHELL32.dll [36E449E0] Hon Mar 08 14,06.24 1999 Bound to MSVCRI.dll [36BB8379] Fri Feb 05 15.49 13 1999 Bound to ADVAPI32.dll [36E449E1] Mon Mar 08 14 06 25 1999 Bound to KERNEL32.dll [36DDAD55] Wed Mar 03 13.44.53 1999 Bound to GDI32 dll [36E449EO] Mon Mar 08 14.06:24 1999 Bound to USER32.dll [36E449EO] Mon Mar 08 14 06 24 1999
Summary
2000 .data
3000 .rsrc
13000 .text
Как видите, в разделе есть записи по каждой DLL, необходимой Calc.exe: Shell32.dll, MSVCRt.dll, AdvAPI32.dll, Kernel32.dll, GDI32.dll и User32dll. Под именем DLL-модуля выводится список идентификаторов, импортируемых программой Calc.exe. Например, Calc.exe обращается к следующим функциям из Kernel32.dll: lstrcpyW, LoсаlAl1ос, GetCommandLineW, GetProfileIntW и др.
Число слева от импортируемого идентификатора называется "подсказкой" (hint) и для нас несущественно. Крайнее левое число в строке для идентификатора сообщает адрес, по которому он размещен в адресном пространстве процесса. Такой адрес показывается, только если было проведено связывание (binding) исполняемого модуля, но об этом — в главе 20.