• VC DLL方法的__declspec导入导出


    https://msdn.microsoft.com/zh-cn/library/a90k134d.aspx

    https://msdn.microsoft.com/zh-cn/library/ms235636.aspx

    可以使用两种方法将公共符号导入到应用程序中或从 DLL 导出函数:

    • 生成 DLL 时使用模块定义 (.def) 文件

    • 在主应用程序的函数定义中使用关键字 __declspec(dllimport)__declspec(dllexport)

    模块定义 (.def) 文件是包含一个或多个描述 DLL 各种特性的 Module 语句的文本文件。 如果不使用 __declspec(dllimport)__declspec(dllexport) 导出 DLL 函数,则 DLL 需要 .def 文件。

    可以使用 .def 文件导入到应用程序中从 DLL 导出

    Visual C++ 用 __declspec(dllimport)__declspec(dllexport) 取代以前在 16 位版的 Visual C++ 中使用的 __export 关键字。

    不使用 __declspec(dllimport) 也能正确编译代码,但使用它可以使编译器生成更好的代码。 编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。 但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。

    如果有正确的 .def 文件 EXPORTS 节,则不需要 __declspec(dllexport)添加 __declspec(dllexport) 是为了提供不使用 .def 文件从 .exe 或 .dll 文件导出函数的简单方法。

    Win32 可移植可执行文件格式旨在最小化为修改导入而必须访问的页数。 为此,它将所有程序的所有导入地址都放在一个称为“导入地址表”的位置。 这使得加载程序在访问这些导入时可以只修改一两页。

    Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib 文件中。 然后,此 .lib 文件就可以像静态 .lib 那样用于与 DLL 链接。

    在更新的编译器版本中,可以使用 __declspec(dllexport) 关键字从 DLL 导出数据、函数、类或类成员函数。 __declspec(dllexport) 会将导出指令添加到对象文件中,因此您不需要使用 .def 文件。

    当尝试导出 C++ 修饰函数名时,这种便利最明显。 由于对名称修饰没有标准规范,因此导出函数的名称在不同的编译器版本中可能有所变化。 如果使用 __declspec(dllexport),仅当解决任何命名约定更改时才必须重新编译 DLL 和依赖 .exe 文件。

    许多导出指令(如序号、NONAME 和 PRIVATE)只能在 .def 文件中创建,并且必须使用 .def 文件来指定这些特性。 不过,在 .def 文件的基础上另外使用 __declspec(dllexport) 不会导致生成错误。

    若要导出函数,__declspec(dllexport) 关键字必须出现在调用约定关键字的左边(如果指定了关键字)。 例如:

     
    __declspec(dllexport) void __cdecl Function1(void);
    

    若要导出类中的所有公共数据成员和成员函数,关键字必须出现在类名的左边,如下所示:

     
    class __declspec(dllexport) CExampleExport : public CObject
    { ... class definition ... };
    
    说明说明

    __declspec(dllexport) 不能应用于具有 __clrcall 调用约定的函数。

    生成 DLL 时,通常创建一个包含正在导出的函数原型和/或类的头文件,并将 __declspec(dllexport) 添加到头文件中的声明中。 若要提高代码的可读性,请为 __declspec(dllexport) 定义一个宏并对正在导出的每个符号使用该宏:

     
    #define DllExport   __declspec( dllexport ) 
    

    __declspec(dllexport) 将函数名存储在 DLL 的导出表中。 如果希望优化表的大小,请参见按序号而不是按名称从 DLL 导出函数

    说明说明

    将 DLL 源代码从 Win16 移植到 Win32 时,请用 __declspec(dllexport) 替换 __export 的每个实例。

  • 相关阅读:
    TIME_WAIT
    Oracle常用SQL命令
    Linux系统标准化设置:克隆系统后网卡设置、固定IP设置、关闭防火墙和SELINUX、更改主机名
    Linux平台oracle 11g单实例 + ASM存储 安装部署
    Oracle基础维护03-主机、数据库日志收集
    print控制台输出带颜色文字方法
    第二十九节,装饰器
    python 浅析对return的理解
    工欲善其事,必先利其器——持续更新中……
    优秀的学习资源收集:
  • 原文地址:https://www.cnblogs.com/liflying/p/4311182.html
Copyright © 2020-2023  润新知