2017-02-17 45 views
-1

我听说导入库有“存根”,所以可执行文件知道我们想要哪个dll和函数。现在我的问题是:那些存根是什么?他们看起来怎么样?可执行文件如何将指针设置为DLL中的正确位置?它是如何知道我们是否在谈论普通库或导入库,因为它们都是.lib文件?导入库如何工作?

+0

另请参阅https://msdn.microsoft.com/en-us/magazine/bb985992.aspx –

+0

可执行文件不知道这些。它是链接器,它会发出适当的代码。 – IInspectable

回答

1

MSVC链接器不直接链接到DLL,它只能链接到静态库(.lib)。

非常粗略地说,一个导入库是一个正常的静态库,对每个DLL导出的函数都有一个存根函数。

例如,如果一个DLL具有的功能void func1()和出口func1,相应的导入库将包含存根函数void __imp__func1() { __asm { jmp dword ptr func1; } }

在运行时,“跳”将采取func1地址从导入表。这就是为什么需要存根。

申请中的声明void __declspec(dllimport) func1();实际上是指__imp__func1()

您可以绕过这整个机制,并在运行时拨打LoadLibraryGetProcAddress以获取地址func1。它会有同样的效果。

1

这取决于您使用的编译器(链接器)和平台。

I.e.在Windows操作系统上,共享库通常是.DLL文件,如果要链接到它(除了动态加载它并在运行时解析其符号),则需要相应的.LIB文件,即存根库。

基本上存根库是重新映射由DLL输出(与__declspec(dllexport))的所有符号中存在的存根和,可以发现,通过使用__declspec(dllimport)程序内的静态链接符号的静态库。

+0

那么__declspec(dllexport)是来自Windows API的函数,还是Visual Studio中的指令? –

+0

@Daniel Nyman:'__declspec'是一个关键字(据我所知,特定于Visual Studio),'dllexport'和'dllimport'是该关键字的属性。更多信息,请访问:https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx – roalz

+0

[__declspec](https://msdn.microsoft.com/en-us/library/dabb5z75.aspx)是一个关键字,它分配一个Microsoft特定的存储类属​​性。 – IInspectable