【问题标题】:Why to use __declspec(dllexport)? Seems to be working without it为什么要使用 __declspec(dllexport)?似乎没有它工作
【发布时间】:2009-10-29 01:36:12
【问题描述】:

我已经有一段时间没有使用 C++ 编程了,所以整个导出/导入的想法从我脑海中消失了。

你能解释一下为什么要使用 __declspec(dllexport) & import thingy 如果看起来我可以使用其他库中的类而不使用这些类。

我在 VC++ 2005 中创建了一个解决方案,添加了控制台应用程序项目和两个 dll 库项目。然后在 LibA 中创建 ClassA,在 LibB 项目中创建 ClassB。

一旦我将 ClassA.h 和 ClassB.h 包含到我的控制台应用程序源代码中,并将它与 LibA.lib 和 LibB.lib 链接起来,我就能够在控制台应用程序中创建和使用 ClassA 和 ClassB 的实例.所以基本上我可以使用类而无需使用 __declspec 导出/导入它们。

你能解释一下 - 我在这里缺少什么。

【问题讨论】:

    标签: c++ visual-c++ visual-studio-2005


    【解决方案1】:

    一旦我将 ClassA.h 和 ClassB.h 包含到我的控制台应用程序源代码中,并将它与 LibA.lib 和 LibB.lib 链接起来,我就能够在控制台应用程序中创建和使用 ClassA 和 ClassB 的实例.

    这听起来像是您使用了静态链接。这在没有__declspec(dllexport) 的情况下也可以工作,就像直接链接到类的目标文件一样。

    如果您想使用与 DLL 的动态(运行时)链接,您必须使用上述声明或指定导出函数的 DEF 文件。 DLL 包含一个导出表,其中列出了暴露给其他可执行文件的函数。所有其他函数都保留在您的 DLL 内部。

    也许您对来自 Linux 世界感到困惑,情况正好相反:默认情况下,所有符号在外部都是可见的。

    【讨论】:

      【解决方案2】:

      如果您想在您的 dll 中提供符号以供其他 dll/exe 访问,您可以使用 __declspec(dllexport)。

      如果您想访问另一个 dll 提供的 dll/exe 中的符号,您可以使用 __declspec(dllimport)。

      如果您要链接静态 .lib,则不需要。

      【讨论】:

      • 那么你是说我只需要那些如果我要与动态 .lib 链接并在运行时加载 dll 吗?
      【解决方案3】:

      如果您包含 .h 文件并链接到 .lib 文件,则可以删除 DLL 声明。如果只需要静态链接,为什么还需要动态链接库?

      导出声明将函数标记为可导出。您正在使用的声明可能是“extern”和“pascal”的宏我已经做了很多年了,但我认为 DLL 函数调用在堆栈上推送参数的顺序不同,并且返回结果的分配是以不同的方式完成(帕斯卡标志)。 extern 声明有助于链接器在您链接库时使函数可用。

      您可能错过了链接 DLL 的步骤 - 链接器将获取 classA.lib 并将其转换为 classA.dll(您可能需要设置 setupA.def 文件来定义 DLL 库)。同样适用于 B 类

      【讨论】:

        猜你喜欢
        • 2018-08-05
        • 2011-11-23
        • 1970-01-01
        • 2023-04-04
        • 2016-03-25
        • 2011-03-28
        • 2023-01-26
        • 2012-07-28
        • 2011-11-20
        相关资源
        最近更新 更多