C++ 全局变量被自身文件/项目内其他文件/动态链接库(DLL)之外文件使用

1 篇文章 0 订阅

一、全局变量的定义和基础使用

全局变量一般定义在一个.cpp文件的头部, 供所在文件乃至其它文件共享使用,供其它文件使用时,不能声明为静态static。

示例1

Test1.cpp

#inclue <stdio.h>

char cTest1[32] = "Hello World!\n";
char cTest2[32] = "Hello My World!\n";

int print_test()
{
    printf("%s", cTest2);    //直接使用全局变量cTest2
    return 0;
}

int main()
{
  //打印出  Hello World!
    printf("%s", cTest1);            //直接使用全局变量cTest1

  //打印出 Hello My World!
    print_test();               
         
    return 0;
}

二、全局变量被其它文件使用

全局变量被其它文件可访问,需要有两个基本条件:

①变量不能声明为静态,否则只能被全局变量所在文件访问,如下示例2是不可以的,按示例1处理即可。

示例2

Test2.cpp

#inclue <stdio.h>


static char cTest1[32] = "Hello World!\n";            //由于使用static关键字修饰,因此只能被本.cpp的成员使用, 其它文件不可见
static char cTest2[32] = "Hello My World!\n";


int print_test()
{
    printf("%s", cTest2);    //直接使用全局变量cTest2
    return 0;
}


int main()
{
  //打印出  Hello World!
    printf("%s", cTest1);            //直接使用全局变量cTest1


  //打印出 Hello My World!
    print_test();               
         
    return 0;
}

②定义全局变量对应的头文件中或其它使用全局变量的文件中,使用extern关键字声明全局变量

(1) 在.h文件中声明

示例3(全局变量的定义如示例1):

Test1.h

extern char char cTest1[32];
extern char char cTest2[32];
Test3.cpp

#include <stdio.h>
#include "Test1.h"    //inculde 被extern 修饰的全局变量所在的头文件

int print_test3()
{
    printf("%s",cTest1);   // 使用全局变量 //当程序被执行时 打印出  Hello World!
    printf("%s",cTest2);   // 使用全局变量 //当程序被执行时 打印出 Hello My World!
    return 0;
}

(2) 在调用全局变量的文件中声明

示例4(全局变量的定义如示例1):

Test:4.cpp

#include <stdio.h>

extern char char cTest1[32];    
extern char char cTest2[32];

int print_test3()
{
    printf("%s",cTest1);   // 使用全局变量 //当程序被执行时 打印出  Hello World!
    printf("%s",cTest2);   // 使用全局变量 //当程序被执行时 打印出 Hello My World!
    return 0;
}

本人的使用习惯是二者同时使用,既在头文件中声明,也在调用的文件中声明。

三、全局变量在动态链接库中定义,被外部文件使用

动态链接库中的全局变量被其它文件可访问,需要有三个基本条件:
①②同上一节中
③在全局变量定义文件中,使用__declspec(dllexport) 声明输出;在全局变量调用的外部文件中,使用__declspec(dllimport)声明输入

针对条件③进行说明:

方便起见,使用如下方式,通过定义宏的方式,定义上面的导入和导出声明

#ifdef _LIBDATAPRO1_EXPORTS    //该宏在VS中, “项目” → “右键” → “属性” → “属性配置” → “C/C++” → “预处理器” → “预处理器定义” 中添加
#define LIBCFGPARA_API __declspec(dllexport)    //若 _LIBDATAPRO1_EXPORTS  已定义 则  LIBCFGPARA_API 定义为输出  __declspec(dllexport)
#else
#define LIBCFGPARA_API __declspec(dllimport)    //若 _LIBDATAPRO1_EXPORTS  未定义 则  LIBCFGPARA_API 定义为输   __declspec(dllimport)
#endif // _LIBDATAPRO_EXPORT

示例5

Test5.cpp

#inclue <stdio.h>

LIBCFGPARA_API char cTest1[32] = "Hello World!\n";            //使用 LIBCFGPARA_API 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
LIBCFGPARA_API char cTest2[32] = "Hello My World!\n";         //使用 LIBCFGPARA_API 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
Test5.h

#ifdef _LIBDATAPRO1_EXPORTS    //该宏在VS中, “项目” → “右键” → “属性” → “属性配置” → “C/C++” → “预处理器” → “预处理器定义” 中添加
#define LIBCFGPARA_API __declspec(dllexport)    //若 _LIBDATAPRO1_EXPORTS  已定义 则  LIBCFGPARA_API 定义为输出  __declspec(dllexport)
#else
#define LIBCFGPARA_API __declspec(dllimport)    //若 _LIBDATAPRO1_EXPORTS  未定义 则  LIBCFGPARA_API 定义为输   __declspec(dllimport)
#endif // _LIBDATAPRO_EXPORT


LIBMAKEPRE_API extern char char cTest1[32];                //使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
LIBMAKEPRE_API extern char char cTest2[32];                //使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   

将上述Test5项目(含Test5.cpp 和 Test5.h文件)进行编译,生成动态链接库,得到Test5.dll和Test5.lib两文件。

Test6.cpp

#include <stdio.h>
#inclue "Test5.h"                                        //(1) include 全局变量对应的Test5.h文件。     由于外部文件的项目中,并没有定义 _LIBDATAPRO1_EXPORTS,因此 LIBCFGPARA_API 被 #else 分支 定义为 __declspec(dllimport)   

#pragma comment(lib, "../x64/Debug/Test5.lib")           //(2) 引用编译生成的.lib库文件

LIBMAKEPRE_API extern char char cTest1[32];              //(3) 使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllimport)   
LIBMAKEPRE_API extern char char cTest2[32];              //(3) 使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllimport)   

int print_test()
{
    printf("%s", cTest2);    //直接使用全局变量cTest2
    return 0;
}

int main()
{
  //打印出  Hello World!
    printf("%s", cTest1);            //直接使用全局变量cTest1


  //打印出 Hello My World!
    print_test();               
         
    return 0;
}

注意:若外部文件在在使用全局变量时, 没有使用输入声明 __declspec(dllimport) ,则VS编译时会有“无法解析的外部符号”编译错误,对比结果如下图所示。

示例6(无 __declspec(dllimport) 声明,编译出错):
在这里插入图片描述
示例6(有 __declspec(dllimport) 声明,编译成功):
在这里插入图片描述
至此,动态链接库中的全局变量,实现了被外部文件的使用。

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值