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

时间:2022-05-03
本文章向大家介绍从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