dllimport 和 dllexport
Dll 在需要暴露接口的头文件里添加 dllexport 声明,比如,
#define DllExport __declspec( dllexport )
class DllExport C {
int i;
virtual int func( void ) { return 1; }
};
注意,禁止对可导出类的成员显式使用 dllimport 和 dllexport 特性。
我们一般情况下会使用预定义宏控制 dll 接口的导入导出,比如,
#include <stdint.h> #ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */ #ifdef __PROJECT_OS_WIN32__
#define PROJECT_API __stdcall
#define DLLIMPORT_C extern __declspec(dllimport)
#define DLLEXPORT_C __declspec(dllexport)
#else
#define PROJECT_API
#define DLLIMPORT_C
#define DLLEXPORT_C __attribute__((visibility("default")))
#endif // __PROJECT_OS_WIN32__ #ifdef __PROJECT_SOURCE__
#define PROJECT_EXPORT DLLEXPORT_C
#else
#define PROJECT_EXPORT DLLIMPORT_C
#endif // __PROJECT_SOURCE__ PROJECT_EXPORT int PROJECT_API project_init(struct xxx**ctx, int x);
这样,我们只要在 Dll 的工程里添加 __PROJECT_OS_WIN32__ 和 __PROJECT_SOURCE__ 预定义宏就可以导出 project_init 接口
同样,我们在使用的时候只要在项目中添加 __PROJECT_OS_WIN32__ 即可导入 project_init 接口,当然,项目中要包含相关接口的头文件
参考:
拓展:
上述第二个链接中提到了 .def 文件,添加该文件也是为了暴露接口,后续可以研究研究
更新:
.def 文件似乎对依赖的静态库暴露的函数无法起到限制作用
缘由:我们在项目中自编译了一个工具静态库,这个库里的函数是由 BASE_EXPORT 做前缀组成,我们在 CMakeLists 中使用 add_subdirectory 添加了子静态库后,最终编译出我们需要的可执行程序,在使用 dumpbin /exports 查看 exe 文件暴露的函数,发现除了预期的 main 函数,还有很多子库的函数,理论上这些子库是不应该暴露的
猜测:在没有编译子静态库时,我们是在主项目中直接调用子文件夹中的源码,那时并没有暴露子文件夹的函数,所以问题是出现在编译成静态库当中
我们知道静态库中所有的函数其实都是暴露给调用的项目的,因为最终主项目在编译过程中,是在链接的过程中到静态库中找到对应的符号文件,而 BASE_EXPORT 并没有阻止主项目中的静态库函数暴露出来
相反,dll 动态库是可以做到这点,究其原因,得后续研究研究了
解决方法:因为静态库的函数是全暴露的,那么我们就不用 #define BASE_EXPORT __declspec(dllexport) 额外暴露的,最后发现主项目编译后没有暴露静态库的函数
旧的:
#if defined(WIN32)
#define BASE_EXPORT __declspec(dllexport)
#else
#define BASE_EXPORT __declspec(dllimport)
#endif
新的:
#if defined(PROJECT_EXPORT)
#if defined(WIN32)
#define BASE_EXPORT __declspec(dllexport)
#else
#define BASE_EXPORT __attribute__((visibility("default")))
#endif
#else
#define BASE_EXPORT
#endif
dllimport 和 dllexport的更多相关文章
- 在C++类中使用dllimport和dllexport导出,
在Windows平台下: 您可以使用dllimport或dllexport属性声明C ++类.这些形式意味着导入或导出整个类.以这种方式导出的类称为可导出类. 以下示例定义可导出的类.导出其所有成员函 ...
- C++ 类中使用dllimport和dllexport
在Windows平台下: 您可以使用dllimport或dllexport属性声明C ++类.这些形式意味着导入或导出整个类.以这种方式导出的类称为可导出类. 以下示例定义可导出的类.导出其所有成员函 ...
- 动态链接库(dll) __declspec(dllimport) __declspec(dllexport)
一. __declspec(dllexport) Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib ...
- VS下 dllimport与dllexport作用与区别
我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...
- dllimport与dllexport作用与区别
我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...
- 浅谈__declspec(dllexport)和__declspec(dllimport)
__declspec(dllimport)和__declspec(dllexport)经常是成对的,在动态链接库中__declspec(dllexport)导出dll中的成员,__declspec(d ...
- [转]从普通DLL中导出C++类 – dllexport和dllimport的使用方法(中英对照、附注解)
这几天写几个小程序练手,在准备将一个类导出时,发现还真不知道如果不用MFC的扩展DLL,是怎么导出的.但我知道dllexport可以导出函数和变量,而且MFC扩展DLL就算是使用了MFC的功能,但 ...
- __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)
转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...
- DLL输入和输出函数—dllinport与dllexport
Microsoft特殊处 dllimport和dllexport存储类修饰符是C语言的Microsoft特殊处扩充.这些修饰显式定义了DLL的客户界面(可执行的文件或另外的DLL).说明为dllexp ...
- (转)_declspec(dllexport)
先看代码:以下是在dev-c++里建立自已的dll时的dll.h里面的代码,这里面有一个:_declspec(dllexport) #ifndef _DLL_H_#define _DLL_H_//防重 ...
随机推荐
- [转帖]Linux命令之——rsync
文章目录 1 rsync是干什么用的 2 rsync和scp有什么区别 3 rsync简单用法介绍 rsync四种工作方式 1. 本地文件系统上实现同步 2. 本地主机使用远程shell和远程主机通信 ...
- [转帖]@Scope("prototype")的正确用法——解决Bean的多例问题
https://www.jianshu.com/p/54b0711a8ec8 1. 问题,Spring管理的某个Bean需要使用多例 在使用了Spring的web工程中,除非特殊情况,我们都会选择 ...
- [转帖]LVS入门篇(四)之LVS实战
LVS入门篇(四)之LVS实战 https://www.cnblogs.com/linuxk/p/9360922.html 一.LVS的NAT模式实战 1.环境说明: HOST OS role rem ...
- Docker镜像精简方法之二 COPY vs ADD 与镜像层
Docker镜像精简方法之二 COPY vs ADD 与镜像层 摘要 昨天只是讲了一下大体的思路. 但是没有实操. 今天想着修改一下默认的打包镜像的命令,验证一下效果 原始命令 FROM adopto ...
- [转帖] Linux命令拾遗-使用blktrace分析io情况
https://www.cnblogs.com/codelogs/p/16060775.html 原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 一般来说,想检 ...
- IPV6的简单学习与整理
背景 大概2018年时曾经突击学习过一段时间IPV6 当时没太有写文档的习惯,导致这边没有成型的记录了. 今天又有项目要求使用IPV6, 想了想就将之前学习的部分 还有想继续学习提高的部分进行一下总结 ...
- FS OFS RS ORS
- CentOS8 的容器运行时解决中文乱码问题的一个思路
首先说明一下 CentOS7和CentOS8关于locale语言文件的位置是不一样的. Docker pull centos 拉取下来的镜像 一般是不带中文语言包的. 简单方法是在 CentOS之后安 ...
- Whisper对于中文语音识别与转写中文文本优化的实践(Python3.10)
阿里的FunAsr对Whisper中文领域的转写能力造成了一定的挑战,但实际上,Whisper的使用者完全可以针对中文的语音做一些优化的措施,换句话说,Whisper的"默认"形态 ...
- locust+python性能测试库
一.简介 locust官网介绍:Locust 是一个用于 HTTP 和其他协议的开源性能/负载测试工具.其对开发人员友好的方法允许您在常规 Python 代码中定义测试.Locust测试可以从命令行运 ...