编辑:试试这样的事情:
__declspec(dllexport) int foo(int param)
{return param*param;}
并编译。事实证明,CRT和kernel32的功能仍然是导入的。我发现它们来自运行时。问题是为什么假设需要这个运行时?我读过一些关于重新安置的事情。这是一个线索吗?
我创建了一个提供Win32 GUI小部件的DLL。如果我查看mingw-gcc生成的dll的导入表,它看起来如下(标有(*)的函数是我自己调用的函数):
导入表(解释.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)标记的功能不应该足够吗?
答案 0 :(得分:1)
C代码运行启动代码。有关这意味着什么的入门读物,请阅读Google上有关"C startup code"
的第一个链接简而言之:它设置堆,堆栈和初始化静态变量,以及诸如“环境”,传递给程序的参数的内存,内部语言环境等等......什么完全< / em>取决于操作系统,编译器和各自的版本。
由于启动代码初始化线程本地存储等等,因此确实链接了依赖关系。您可以在与gcc链接时添加-nodefaultlibs
来阻止此操作(至少部分),但请注意:Dragons Ahead!