从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:

  #define OS_API_EXPORT __declspec(dllexport)

  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

复制代码
    #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;}
复制代码

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

转自:http://www.cnblogs.com/darknightsnow/archive/2012/09/25/2701389.html



补充:

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值