【问题标题】:Why doesn't __declspec(dllimport) work with memcpy() in Visual C++? How do I make it work?为什么 __declspec(dllimport) 在 Visual C++ 中不能与 memcpy() 一起使用?我如何使它工作?
【发布时间】:2021-08-30 04:50:25
【问题描述】:

我注意到 __declspec(dllimport) 不适用于 Visual C++ 中的 memcpy。
即链接器introduces a jmp thunk,不管dllimport,这样就可以代替

    call    QWORD PTR __imp_memcpy

我明白了

    call    memcpy

这种行为的原因是什么?如何消除memcpy 的跳转开销?

【问题讨论】:

  • #pragma function(memcpy) 在优化的发布版本中修复它。但确实会扼杀优化选项,因此请将其隔离在您关心的翻译单元中。
  • @HansPassant:你确定吗? It doesn't work for me。另外,您是否知道在不终止优化的情况下获得dllimport 的任何方法?我一直在尝试所有我能想到的东西(甚至是内联汇编、.def 文件、弄乱目标文件符号等)但都失败了——似乎不仅仅是编译器,还有 链接器拒绝将memcpy 导入为__imp_memcpy,就像使用任何其他函数一样。

标签: c optimization visual-c++ dllimport


【解决方案1】:

当翻译单元包含 not dllimported 的函数声明时,这似乎会发生。 但是,包括编译器在/Oi 下的隐式声明(/O2 隐含)。

因此,避免这个问题需要做两件事:

  1. 将memcpy 的所有声明修改为__declspec(dllimport)。
    (这可能需要通过#define memcpy bad_memcpy 等进行宏黑客攻击。)

  2. 用/Oi-编译,防止引入内部声明。

不幸的是,这是一个不能令人满意的解决方法,因为它似乎抑制了 memset... 的编译器优化,我不知道有什么方法可以同时解决这个问题。 还有其他人知道如何避免这个问题吗?

另请注意,在 IDE 中禁用项目属性中的内在函数可能不足够,因为 Visual C++ 不一定会发出 /Oi-,因此如果它认为选项已经存在禁用。 (这似乎也是一个错误。)

确实,we see the issue is fixed when we do this:

   call    QWORD PTR __imp_memcpy

我认为这是一个错误...编译器的内部声明不应覆盖用户指定的声明。

【讨论】:

    猜你喜欢
    • 2011-06-10
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    相关资源
    最近更新 更多