gpt4 book ai didi

c++ - Visual Studio 中 dllimport 的用例

转载 作者:行者123 更新时间:2023-12-03 07:12:06 25 4
gpt4 key购买 nike

我一直想知道__declspec(dllimport)的真正用例是什么。我知道构建共享库需要使用 __declspec(dllexport) 导出其符号,然后库的用户将这些符号用作 __declspec(dllimport) 。

然后,您应该使用特殊的定义来构建共享库,该定义启用dllexport,如果未设置该标志,则符号将定义为dllimport

但是,我根本没有使用过dllimport,而且它确实有效。

我有两个项目:

导入导出

有一个小的 Util 类,它是使用定义的 EXPORTING 构建的

Util.h:

#ifndef _UTIL_H_
#define _UTIL_H_

#if defined(EXPORTING)
# define EXPORT __declspec(dllexport)
#else
# define EXPORT // I should use __declspec(dllimport) but client will try out
#endif

class EXPORT Util {
public:
static void test();
};

#endif // !_UTIL_H_

然后在源文件Util.cpp中:

#include <iostream>

#include "Util.h"

void Util::test()
{
std::cout << "Testing..." << std::endl;
}

没什么复杂的,正如你所看到的,当用户使用这个文件时,EXPORT根本不会被定义(它应该被定义为dllimport)。

客户端可执行文件

main.cpp :

#include <Util.h>

int main(void)
{
Util::test();

return 0;
}

链接到 ImportExport.lib 无需任何定义集,即可正常工作。没有 undefined reference 。

我想知道为什么要使用 dllimport 的用例?它的存在是为了向后兼容吗?

注意:所有提供的代码都在 VisualStudio 2012 Express 上进行了测试。

最佳答案

Raymond Chen在this series中详细描述了dll导入机制;总结一下,函数的dllimport本质上是一种性能优化。

如果您不将函数标记为dllimport,编译器和链接器 will treat it as a normal function ,使用“静态”函数调用将其解析为导入库中找到的 stub 。 stub 实际上必须从 IAT 获取导入函数的地址并在那里执行 jmp (即它必须以某种方式将编译器生成的直接调用转换为间接调用),因此有一些这两个步骤过程中的性能损失。

相反,

dllimport 告诉编译器 it has to generate code for an indirect call从编译阶段就通过 IAT。这减少了间接寻址并允许编译器缓存(在函数本地)目标函数地址。

请注意,as MSDN says ,您可以仅针对函数省略dllimport;对于数据来说,它始终是必要的,因为链接器没有一种机制可以以间接方式重新处理对编译器生成的变量的直接访问。

(所有这些在“经典”链接器时代尤其相关;如今,启用链接时代码生成后,只需让链接器完全生成函数调用/数据访问即可解决所有这些问题)

关于c++ - Visual Studio 中 dllimport 的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24671021/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com