windows __declspec(dllimport)的必要性

wi3ka0sx  于 2023-04-22  发布在  Windows
关注(0)|答案(3)|浏览(154)

我在看这个Importing Function Calls Using __declspec(dllimport)和我不明白为什么真的需要__declspec(dllimport)?为什么链接器不能在链接阶段将调用func1补丁到调用DWORD PTR__imp_func1(IAT表地址),从而避免在源代码中单独声明的需要?

jtw3ybtb

jtw3ybtb1#

没有足够的空间来修补指令可能是一个原因,但不是主要原因。即使有足够的空间,链接器仍然不会为了更好的性能而修补它。原因是链接器不做或修改编译器后端生成的代码,它只是用重定位信息修补位置。下面的例子不是很好的编码风格,但是要清楚地解释这个问题。为bar()生成的指令是call dword[_imp__bar],它是6个字节长,即使链接器知道bar()是在最终映像中定义的,它不会用call OffsetOfBar打补丁,call OffsetOfBar只需要5字节。(将/GL传递给cl.exe)可以解决此问题,因为链接器将在链接时调用编译器后端,并且后端将生成优化的call指令,因为它知道call目标在同一模块中。

// main.c
// compile it with 'cl.exe /Zi /O2 main.c bar.c'

__declspec(dllimport) void bar();

int main() {
  bar();
}

// bar.c
void __declspec(noinline) bar() {}
3npbholx

3npbholx2#

引用Raymond Chen的话:call func的长度是5个字节,但call dword ptr [_imp_func]的长度是6个字节。这个补丁不适合。它太大了一个字节。在每个call指令之后添加一个nop(以防它碰巧被导入)听起来相当过分。

vjrehmav

vjrehmav3#

在VS 2022中(可能在很久很久以前),编译器(而不是链接器)确实能够在有或没有__declspec(dllimport)的情况下优化形实转换程序。今天它完全是多余的,希望有一天文档会反映出来。

相关问题