Вызовы функций, необходимые для инициализации DLL - PullRequest
0 голосов
/ 13 марта 2012

РЕДАКТИРОВАТЬ: Просто попробуйте что-то вроде этого:

__declspec(dllexport) int foo(int param)
    {return param*param;}

и скомпилируйте.Оказывается, функции из CRT и kernel32 по-прежнему импортируются.Я обнаружил, что они приходят из среды выполнения.Вопрос в том, почему предполагается, что это время выполнения необходимо?Я прочитал кое-что о переездах.Это ключ?

Я создал DLL, которая предоставляет Win32 GUI виджет.Если я посмотрю на таблицу импорта для dll, сгенерированной mingw-gcc, она будет выглядеть следующим образом (функции, отмеченные (*) - это те, которые я сам назвал):

Импорт таблиц (интерпретированное содержимое раздела .idata)

vma:            Hint    Time      Forward  DLL       First
                Table   Stamp     Chain    Name      Thunk
00006000    00006050 00000000 00000000 00006354 000060d4

DLL Name: KERNEL32.dll
vma:  Hint/Ord Member-Name Bound-To
6158      207  DeleteCriticalSection
6170      236  EnterCriticalSection
6188      352  FreeLibrary
6196      510  GetLastError
61a6      529  GetModuleHandleA  (x)
61ba      577  GetProcAddress
61cc      734  InitializeCriticalSection
61e8      814  LeaveCriticalSection
6200      817  LoadLibraryA
6210     1173  TlsGetValue
621e     1213  VirtualProtect
6230     1215  VirtualQuery

00006014    00006084 00000000 00000000 00006394 00006108

DLL Name: msvcrt.dll
vma:  Hint/Ord Member-Name Bound-To
6240       52  __dllonexit
624e      182  _errno
6258      266  _iob
6260      538  _winmajor
626c      583  abort
6274      595  calloc
627e      610  fflush
6288      625  free    (x)
6290      633  fwrite
629a      676  malloc  (x)
62a4      682  memcpy  (x)
62ae      748  vfprintf

00006028    000060b8 00000000 00000000 000063b8 0000613c

DLL Name: USER32.dll
vma:  Hint/Ord Member-Name Bound-To
62ba      134  DefWindowProcA    (x)
62cc      342  GetWindowLongA    (x)
62de      405  LoadCursorA       (x)
62ec      480  RegisterClassExA  (x)
6300      508  SendMessageA      (x)
6310      569  SetWindowLongA    (x)

Кажется, есть много дел, прежде чем я действительно смогу использовать DLL.Например, я никогда не использовал fwrite в своем коде, но он отображается в таблице импорта.Это указывает на то, что он используется в некоторой подпрограмме инициализации, которую компилятор добавляет при компоновке. Почему?Разве функций, помеченных (x), не должно быть достаточно?

Ответы [ 2 ]

1 голос
/ 07 июня 2012

C-код запускает код запуска.Чтобы понять, что это значит, прочитайте, например, первую ссылку в Google о «Код запуска C»

Вкратце: он устанавливает кучу, стек и инициализирует статические переменные, а такжес такими вещами, как «среда», память для параметров, передаваемых программе, внутренняя локаль и т. д. Что именно точно зависит от ОС, компилятора и соответствующих версий.

зависимости действительно связаны из-за кода запуска, который инициализирует локальное хранилище потока и еще много чего.Вы можете предотвратить это (хотя бы частично), добавив -nodefaultlibs при связывании с gcc, но будьте осторожны: Dragons Ahead!

1 голос
/ 13 марта 2012

Я создал dll, который предоставляет виджет графического интерфейса Win32.

Достаточно лидерства, вы не можете писать виджеты Win32 без использования функций Win32 API.Вот что показывают ваши дампы таблицы импорта.Вы всегда будете зависеть от kernel32.dll, основного API Windows.Вы получите зависимость от user32.dll, когда будете что-либо делать с Windows.Зависимость msvcrt.dll генерируется mingw, она связывает динамическую версию библиотеки времени выполнения Microsoft C.

Все нормально, загрузчик Windows гарантирует, что эти библиотеки DLL загружаются и связываются при запуске вашей программы.

...