从static变量导出问题解析 __declspec(dllexport) 和 __declspec(dllimport)的作用

 这段时间要把tinyxml从静态库弄成动态库,要用到__declspec(dllexport)和__declspec(dllimport)来导出dll和lib文件。终于弄明白了export和import的作用,下面从使用的角度来说明一下他们的功能。

  首先要知道,头文件是C++的接口文件,不仅本工程需要使用头文件来进行编译,给其他工程提供dll的时候也要提供此dll的头文件才能让其他人通过编程的方式来使用dll。记住:头文件要给自己用还要给别人用。

  比如一个项目中的Class中含有一个静态变量,生成dll的时候只采用了__declspec(dllexport) 如下:

dll工程

A1.h:

[cpp] view plaincopy
  1. #define OS_API_EXPORT __declspec(dllexport)  
  2.   
  3. class OS_API_EXPORT A {static int a;}  


A.cpp:

  #include “A.h”static A::a=0; //静态变量的初始化要写在cpp文件中

  这样做的时候编译dll工程的时候没有问题,但是如果把dll和头文件提供给别人使用的时候就会出“unsloved symbol a”的问题。

  原因是静态成员如果不import,是不能够被编译器从lib文件里找到的。

  使用dll的工程在编译时也会将dll相关的头文件列入编译对象,而不会理会dll的cpp文件中的初始化过程,因此会出现a没有定义的情况,这时

__declspec(dllimport)就派上用场了,他会告诉使用dll的工程去lib中找到这个静态变量的定义。提供给别人使用的dll头文件应当写成:

A2.h:

  #define OS_API_IMPORT __declspec(dllimport)class OS_API_IMPORT A {static int a;}

  当使用A.dll的工程链接上A2.h后,就不会出现“unsloved symbol a”的问题了。

最终为了方便程序的开发,不用分别写出dll工程的头文件和使用dll工程的头文件,头文件可以写为如下形式:

A.h

[cpp] view plaincopy
  1. #define OS_API_IMPORT __declspec(dllimport)  
  2. #define OS_API_EXPORT __declspec(dllexport)  
  3.   
  4. #ifdef BUILD_DLL  
  5. #define OS_API OS_API_EXPORT //如果是生成dll工程,那么导出  
  6. #else  
  7. #define OS_API OS_API_IMPORT //如果是生成使用dll的工程,那么导入  
  8. #endif   
  9.   
  10. class OS_API A{static int a;}  

同时别忘了在dll工程属性下设置预处理器定义BUILD_DLL


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4月26日作业

2016年4月26日作业 一、项目整体绩效评估1、*三E审计是什么的合称?(记) 答:经济审计,效率审计和效果审计2、霍尔三维结构是从哪三个方面考察系统工程的工作过程的? 答:逻辑,时间和知…

xcode8 快捷键失效

因为苹果解决xcode ghost,把插件屏蔽了。 解决方法: 命令运行: sudo /usr/libexec/xpccachectl 然后必须重启电脑后生效

CAS单点登录配置[3]:服务器端配置

在准备工作,证书生成等工作完成后,本篇介绍服务器端的配置。 JDK配置 1我们将生成的cacerts文件分别拷贝到JDK目录下的jre/lib/security目录下及JRE对应的目录中,如果之前存在此文件,请替换; ENDTomcat配置 1Step 1:将…

DLL动态链接库的工作原理

"动态链接"这几字指明了DLLs是如何工作的。 对于常规的函数库,链接器从中拷贝它需要的所有库函数,并把确切的函数地址传送给调用这些函数的程序。 而对于DLLs,函数储存在一个独立的动态链接库文件中。在创建Windows程序时&#xff…

remind程序

2019独角兽企业重金招聘Python工程师标准>>> 用了两个定时器。一个控制刷新时间,一个控制响铃。 定时器响应函数Timer: int wk; if(nIDEvent1) { CTime tCTime::GetCurrentTime(); wkt.GetDayOfWeek()-1; m_mnt.Format("%Y 年 …

查看手机是否安装微信客户端

if (![[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:"weixin://"]] ) {[wcatBtn setHidden:YES];}

Caffe学习系列(7):solver及其配置

solver算是caffe的核心的核心,它协调着整个模型的运作。caffe程序运行必带的一个参数就是solver配置文件。运行代码一般为 # caffe train --solver*_slover.prototxt 在Deep Learning中,往往loss function是非凸的,没有解析解,我们…

Qt DLL总结-创建及调用QT的 DLL

目录 Qt DLL总结【一】-链接库预备知识 Qt DLL总结【二】-创建及调用QT的 DLL Qt DLL总结【三】-VS2008Qt 使用QPluginLoader访问DLL 开发环境:VS2008Qt4.7.4 最近看了不少Qt的DLL例子,总结一下如何创建和调用QT 动态链接库。 先讲一下对QT动态链接库的…

Unable to install pirate

真机测试的时候,报这个错误,主要原因就是证书的问题 xcode7以上进行的真机测试,可以没有使用证书,xcode可以进行的傻瓜操作帮助我们完成真机测试,但是今天我进行真机测试的时候报这个错误,同时xcode也不进…

memmove 对同一个指针不操作

memmove 对同一个指针不操作,所以调用memmove之前不用比较两个指针是否相同 void CTestDLLDlg::OnBnClickedButton6() {const int size 999999;char* data new char[size];memset(data, 1, size - 1);char* data1 new char[size];memset(data1, a, size - 1);clo…

.Net JIT

.Net JIT(转) JIT 转载于:https://www.cnblogs.com/HelloMyWorld/p/5501135.html

Hadoop HDFS概念学习系列之HDFS升级和回滚机制(十二)

不多说,直接上干货! HDFS升级和回滚机制 作为一个大型的分布式系统,Hadoop内部实现了一套升级机制,当在一个集群上升级Hadoop时,像其他的软件升级一样,可能会有新的bug或一些会影响现有应用的非兼容性变更出…

TCP协议的特性

TCP协议的特性:建立连接:三次握手将数据打包成段:校验和(CRC32)确认、重传及超时排序:逻辑序号流量控制:滑动窗口算法拥塞控制:慢启动和拥塞便面算法转载于:https://blog.51cto.com/…

属性动画基础之ValueAnimator

概述 属性动画是谷歌在android3.0(API level 11)时候给我们带来了属性动画,真正意义上带来了”动画“,以前的帧动画也就4中效果的组合(旋转、淡入淡出、放大缩小、平移),而且只是表面的动画&…

经验之谈:10位顶级PHP大师的开发原则

导读:在Web开发世界里,PHP是最流行的语言之一,从PHP里,你能够很容易的找到你所需的脚本,遗憾的是,很少人会去用“最佳做法”去写一个PHP程序。这里,我们向大家介绍PHP的10种最佳实践&#xff0c…

#Pragma Pack(n)与内存分配 pragma pack(push,1)与#pragma pack(1)的区别

from:http://blog.csdn.net/mylinx/article/details/7007309 #pragma pack(n) 解释一: 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n1,2,4,8,16来改变这一系数,…

ShowDoc的搭建

其实,官方文档也说的很清楚了。主要贴一下我遇见的问题。环境:LNMP(LAMP没试过,有兴趣的同学可以试试,然后发出来)PHP5.3以上版本、php-mbstring模块、php-pdo模块、mysql数据库克隆或者下载代码&#xff1…