栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Windows 下编程,关于导入导出的一些验证和说明

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Windows 下编程,关于导入导出的一些验证和说明

文章目录
      • 场景一:声明和实现都在 `.h` 文件中时,给外部模块用,需不需要导入导出 ?
      • 场景二:声明和实现分开在 `.h` `.cpp`文件中时,给外部模块用,需不需要导入导出 ?
      • 场景三:声明和实现分开在 `.h` `.cpp`文件中时,给外部模块用,只导出需要的函数接口行不行 ?
      • 场景四: 给外部使用的枚举需要显式导入导出么?常量需要导入导出么?
      • 释疑与总结
      • 题外话

通常情况下,开发者在用到 __declspec(dllexport) 和 __declspec(dllimport) 时,大多数是为了本模块的接口供模块外的功能使用。但在开发过程中,常常保持着 “不知道该不该用,但用了不会出错” 的原则,从而滥用的情况,现在就几种典型场景进行说明。

我们编写如下测试代码:
两个独立的 dll 模块 panny_dll panny_dll_test。
我们在 panny_dll 模块中定义我们需要验证的对象。在 panny_dll_test 中测试。

场景一:声明和实现都在 .h 文件中时,给外部模块用,需不需要导入导出 ?



运行结果如下:


说明这种情况下,不需要导入导出标识。

场景二:声明和实现分开在 .h .cpp文件中时,给外部模块用,需不需要导入导出 ?



链接报错:


说明,声明、实现分开写在.h .cpp文件中时,如果不导出,会出现问题。

原因是外部在调用这个接口时,没有被导出,链接时找不到这个函数。

我们在写这个函数的时候也确实没有导出,所以会出现这种情况。

那么为什么声明和实现都写在 .h 中的时候没问题呢?

这就涉及到C++ 的编译链接逻辑了。

我们在编译时,一般会将.cpp编译为.obj文件,一个.cpp对应一个.obj;链接时,根据需要将多个obj组成.lib,或者生成.dll。

而导入导出的本质,其实就是为了让其他模块的代码感知本模块的.cpp文件。

那么没有 .cpp 文件,理论上就没有 dll 文件,用户拿到包含实现代码的头文件就应该可以用,这就不存在声明导入导出了。

场景三:声明和实现分开在 .h .cpp文件中时,给外部模块用,只导出需要的函数接口行不行 ?



运行结果:


说明,可以在不导出类的情况下,按需导出接口函数。

场景四: 给外部使用的枚举需要显式导入导出么?常量需要导入导出么?



结果:


说明: 枚举和常量如果在头文件中定义了,外部是可以通过包含头文件直接使用的。

释疑与总结

导入导出的本质是为了让其他模块的代码感知本模块的.cpp文件。

我们在编译时,一般会将.cpp编译为.obj文件,一个.cpp对应一个.obj;链接时,根据需要将多个obj组成.lib,或者生成.dll。

  • 对于声明和实现分别在.h和.cpp的部分,如果没有标识导入导出,那么默认的只能在本模块使用。

  • 如果声明和实现均在.h中的话,那其实是没有对应的.dll文件的,默认的是全局作用域,对所有模块都可见。我们看到的枚举就是这种情况。还有全部的模板类都这这种情况。

  • 如果声明和实现分别在.h和.cpp的部分,并且标识导入导出,那就是本模块能使用,外部模块也能使用。

题外话

doxygen 在根据注释生成文档时,有一个很有意思的现象,就是当且仅当枚举被标识导入导出时,会注释识别失败,官方文档也没找到有效说明。也许是有意为之,也许就是个隐藏的BUG。不过将枚举标识导入导出,本身就是多此一举的,或许 doxygen 也有这种考量,才会不识别吧。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873034.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号