__declspec(dllexport) 和 __declspec(dllimport)

简介: __declspec(dllexport) 和 __declspec(dllimport)

1.简单介绍

__declspec(dllexport) 和 __declspec(dllimport) 是用来导出和导入 DLL 中的符号的。通常,当你创建一个 DLL 时,你会创建一个包含要导出的函数原型和/或类的头文件,并将 __declspec(dllexport) 添加到头文件中的声明内。为了提高代码的可读性,可以为 __declspec(dllexport) 定义宏,并对要导出的每个符号使用此宏1。

#ifdef 是一个预处理指令,用于检查宏是否已定义。在这种情况下,它可以用来确定代码是在 DLL 中编译还是在使用 DLL 的应用程序中编译。如果是在 DLL 中编译,则使用 __declspec(dllexport) 来导出符号;否则,使用 __declspec(dllimport) 来导入符号。

例如,可以这样写头文件:

#define OS_API_IMPORT __declspec(dllimport)
#define OS_API_EXPORT __declspec(dllexport)
#ifdef BUILD_DLL
#define OS_API OS_API_EXPORT // 如果是生成dll工程,那么导出
#else
#define OS_API OS_API_IMPORT // 如果是生成使用dll的工程,那么导入
#endif
class OS_API A {static int a;};

这行代码定义了一个名为 `A` 的类,该类具有一个名为 `a` 的静态整数成员。`OS_API` 是一个宏,它的值取决于是否定义了 `BUILD_DLL` 宏。如果定义了 `BUILD_DLL` 宏,则 `OS_API` 被定义为 `__declspec(dllexport)`,用于导出符号;否则,`OS_API` 被定义为 `__declspec(dllimport)`,用于导入符号。

因此,在编译 DLL 时,只需定义 `BUILD_DLL` 宏,就可以使用 `OS_API` 宏来导出类 `A`。在使用 DLL 的应用程序中,不需要定义 `BUILD_DLL` 宏,可以使用 `OS_API` 宏来导入类 `A`。

可以把一个DLL比作一个商店,而函数和变量就是商店里的商品。`__declspec(dllexport)`就像是商店的招牌,它告诉顾客(其他程序)这家商店有哪些商品(函数和变量)可以购买(使用)。而`__declspec(dllimport)`就像是顾客的购物清单,它告诉商店(DLL)顾客(当前程序)想要购买哪些商品(函数和变量)。这样,商店就能够提供给顾客想要的商品,而顾客也能够在自己的程序中使用这些商品。

2.例子

下面是一个简单的例子,它演示了如何使用`__declspec(dllexport)`和`__declspec(dllimport)`来导出和导入函数。

首先,我们创建一个DLL,它包含一个名为`Add`的函数,用于计算两个整数的和。我们使用`__declspec(dllexport)`来将该函数从DLL中导出。

// MyLibrary.h
#ifdef MYLIBRARY_EXPORTS
#define MYLIBRARY_API __declspec(dllexport)
#else
#define MYLIBRARY_API __declspec(dllimport)
#endif
MYLIBRARY_API int Add(int a, int b);
// MyLibrary.cpp
#include "MyLibrary.h"
int Add(int a, int b) {
    return a + b;
}

然后,我们创建一个程序来使用这个DLL。我们使用`__declspec(dllimport)`来从DLL中导入`Add`函数。

// main.cpp
#include <iostream>
#include "MyLibrary.h"
int main() {
    int result = Add(1, 2);
    std::cout << "The result is: " << result << std::endl;
    return 0;
}

在这个例子中,我们使用了条件编译来定义一个宏`MYLIBRARY_API`,它根据是否定义了`MYLIBRARY_EXPORTS`来决定使用`__declspec(dllexport)`还是`__declspec(dllimport)`。当我们编译DLL时,我们需要定义`MYLIBRARY_EXPORTS`,这样就会使用`__declspec(dllexport)`来导出函数。当我们编译使用DLL的程序时,我们不需要定义`MYLIBRARY_EXPORTS`,这样就会使用`__declspec(dllimport)`来导入函数。

简单讲,就是一个是给编译dll时自身用的,一个是其他程序需要调用dll用的

相关文章
|
算法 数据可视化
Halcon边缘检测和线条检测(3),文章含BLOB检测常用方法和shape_trans内接和外接算子的说明
Halcon边缘检测和线条检测(3),文章含BLOB检测常用方法和shape_trans内接和外接算子的说明
2815 0
Halcon边缘检测和线条检测(3),文章含BLOB检测常用方法和shape_trans内接和外接算子的说明
|
编译器 Linux C语言
C/C++ 常见函数调用约定(__stdcall,__cdecl,__fastcall等):介绍常见函数调用约定的基本概念、用途和作用
C/C++ 常见函数调用约定(__stdcall,__cdecl,__fastcall等):介绍常见函数调用约定的基本概念、用途和作用
1141 0
|
8月前
|
SQL 数据库连接 数据库
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
498 14
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
1245 162
|
C语言 C++ Windows
QT多插件通信框架CTK编译记录
本文记录了编译QT多插件通信框架CTK的过程,包括编译结果截图、部署配置、Log4Qt编译配置、参考链接和拓展资料。文中提供了详细的编译步骤和配置文件示例,以及相关的资源链接。
634 0
QT多插件通信框架CTK编译记录
|
IDE Unix 编译器
Windows下配置CMake(入门级教程,适合新人收藏学习)
Windows下配置CMake(入门级教程,适合新人收藏学习)
6031 1
|
安全 算法 Java
多线程写入同一个文件时,如何保证写入正常
【9月更文挑战第3天】多线程写入同一个文件时,如何保证写入正常
1601 8
|
Unix
深入理解 CMake 的 `cmake --build` 命令
深入理解 CMake 的 `cmake --build` 命令
2330 1
|
XML 数据可视化 程序员
Qt 中的项目文件解析和命名规范
Qt 中的项目文件解析和命名规范
|
Ubuntu 编译器 C++
【Conan 入门教程 】在Ubuntu上使用Conan编译C++第三方库:一站式解决方案
【Conan 入门教程 】在Ubuntu上使用Conan编译C++第三方库:一站式解决方案
3642 1

热门文章

最新文章