从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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏LhWorld哥陪你聊算法

【Dubbo篇】--Dubbo框架的使用

Provider: 提供者.发布服务的项目. Registry: 注册中心.所有提供者必须去注册中心注册自己所有能发布的服务. Consumer: 消费者.调用...

3181
来自专栏IT 指南者专栏

【SSH框架】之Struts2系列(二)

微信公众号:compassblog 欢迎关注、转发,互相学习,共同进步! 有任何问题,请后台留言联 1、Struts2常量配置 (1)、Struts2默认常量配...

33512
来自专栏游戏杂谈

使用node-webkit实现打包工具的小结

之前一直使用的hta在开发工具,最近转到node-webkit上了,对比一下二者的优劣势。hta单个文件,体积较小,但有兼容性的问题(兼容ie6、7、8就行了...

1422
来自专栏Golang语言社区

Golang语言 的跨域解决

在使用golang做web的应用程序的时候,最容易碰到跨域问题了,跨域就是www.a.com访问[url]www.b.com[/url]的文件。但是在浏览器里,...

3098
来自专栏我的博客

Zend_Http之Zend_Http_Client

$client = new Zend_Http_Client(‘http://192.168.1.180/index/get’, array( ‘maxred...

2954
来自专栏北京马哥教育

Python爬虫基础知识:urllib2的使用技巧

糖豆贴心提醒,本文阅读时间6分钟 前面说到了urllib2的简单入门,下面整理了一部分urllib2的使用细节。 1.Proxy 的设置 urllib2 默认...

2915
来自专栏nummy

Django生产环境下如何查看Debug信息

我们知道,部署Django到生产环境时,settings.DEBUG必须设置为False, 否则会带来很大的安全隐患。

862
来自专栏蓝天

一种基于Redis的10行代码实现IP频率控制方法

优点:可支持海量访问的频率控制,只需要增加Redis机器,单个Redis节点(只占用一个cpu core)即可支持10万/s以上的处理。 基于IP频率限制是种...

853
来自专栏bboysoul

ubuntu使用sslocal连接shadowsocks

今天更新了一下系统,更新了一个包libqtshadowsocks,之后shadowsocks-qt5就打不开了,在网上也没有找到低版本的这个包,报错信息如下

2011
来自专栏章鱼的慢慢技术路

错误代码CS0051可访问性不一致_解决方案

本来对BaseStruct设置为私有访问,但调用时又想公开化,从而造成了编译错误。

1062

扫码关注云+社区