首页
社区
课程
招聘
[讨论]一定要在头文件中申明全局变量或实现函数,而且要保持唯一性,应该怎么办?
发表于: 2013-10-29 11:44 14527

[讨论]一定要在头文件中申明全局变量或实现函数,而且要保持唯一性,应该怎么办?

2013-10-29 11:44
14527
因为我要帮别人写一些开发工具类,代码只能写在头文件中,不能写在cpp里,别人只要include我的.h就行了,我的代码有些复杂,一定得用到全局变量

全局变量一但被多个文件包含,就会冲突,
那请问,c或c++里,有没有办法在头文件里声明个全局变量,被多个cpp包含时还能保证唯一性?

补充:
我写的东东类似于SDK,代码全实现在.h里,别人只需要include "xx.h"一行就行了,就能使用我的所有东西了
不需要lib库,不需要添加cpp文件
只是因为我的代码里用到了全局变量,会导致冲突,所以看有没有解决方案,能实现全局变量唯一性

同理:
有些函数要写成static函数的话,如果实现在.h中,会导致该函数生成多份实现,增加生成exe的体积
不加static函数的话,跟上面说的全局变量一样,会冲突

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (39)
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
extern ULONG Var.
2013-10-29 11:49
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
cpp文件里直接弄变量,h文件里就 extern ULONG Var.这样声明就直接能用了.
2013-10-29 11:50
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
我的代码只有.h,没有cpp,所以不行
2013-10-29 11:54
0
雪    币: 100
活跃值: (323)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
static
2013-10-29 11:56
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
原来也是static,前段时间才知道,误解了static的含义,不能使用,所以来求办法
2013-10-29 11:58
0
雪    币: 238
活跃值: (55)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
原来还有这种没有cpp的方法,多文件编译时应该很复杂
2013-10-29 12:02
0
雪    币: 238
活跃值: (55)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
#pragma once
不知道管不管用
2013-10-29 12:08
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
不行的……
2013-10-29 12:09
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
class PP
{
public:
  static int ms_x;
}

__declspec(selectany) int PP::ms_x = 0;
2013-10-29 12:10
0
雪    币: 238
活跃值: (55)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
11
看样子是对的
2013-10-29 12:16
0
雪    币: 209
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
static了之后,有多个cpp使用这个头文件,就有了多个互不相关的同名全局变量了
2013-10-29 14:30
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
就是这样 ,所以我去static后,面临问题了,看大家有解决办法不
2013-10-29 14:37
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
static解决不了问题,还会导致错误,多份同名变量
2013-10-29 14:38
0
雪    币: 659
活跃值: (499)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
15
#define	Param0	0
#define	Param1	4
#define	Param3	8

_declspec(naked)  VOID Init()
{
	VirtualAlloc(NULL, 1024, MEM_COMMIT, RAGE_READWRITE);
	_asm
	{
		mov		ebx, eax
	}
	
}
这样ebx就用来保存你申请的内存首地址,所有的全局变量就用这块内存来保存

假如要使用Param0变量
	_asm
	{
		mov		eax, ebx
		add		eax, Param0
	}

这样eax就是存放Param0的地址,取值即可,当然eax也可以换成你定义的局部变量,最后记得释放内存即可

这样比较麻烦,方面的话可以用宏,一般来说程序不会用到ebx指令,即使一些API用到也会在调用完后恢复,当然某些程序要不遵守规则那也没办法
2013-10-29 14:44
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
不复杂啊
好比我写的是个sdk,人家只需要include就行了,不需要增加cpp,不需要添加lib,使用很简单的
只不过我的实现里需要用到全局变量,才出现了难题,解决这个就ok了
2013-10-29 14:44
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
工程一大,东西就多,你这方法貌似增加工作量很大呀
还有,全局变量,当然会在多个函数中被使用,ebx就已经被废啦,所以你这方法,应该行不通
2013-10-29 14:53
0
雪    币: 659
活跃值: (499)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
18
还一种方法就是利用进程的共享内存,0x7FFE0000这个是起点,任何程序都可以用,把你的全局变量保存在这里,要用的时候加上0x7FFE0000就可以得到你全局变量的指针,然后取值即可,当然这种方法要注意没有其他人用共享内存,但好像除了一些特殊的程序会用之外一般没人用。
#define	cParam0	0
#define	cParam1	4
#define	cParam2	8

Addr_Param0 = 0x7FFE0000 + cParam0;
*Addr_Param0 = 5;
2013-10-29 14:57
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
这问题微软都解决不了
MFC的例子里,app对象都是用extern声明在头文件里,然后在cpp里定义.
所以楼主你的所有文件都做成h文件,其实是很不好的习惯.
2013-10-29 14:57
0
雪    币: 100
活跃值: (323)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20

#include "boost/noncopyable.hpp"

template <typename T>
struct Singleton  : public boost::noncopyable
{
	struct object_creator
	{
		object_creator(){ Singleton<T>::GetInstance(); }
		inline void do_nothing()const {}
	};
	
	static object_creator create_object;

public:
	typedef T object_type;
	static object_type& GetInstance()
	{
		static object_type obj;
		create_object.do_nothing();
		return obj;
	}
};

template <typename T>
typename Singleton<T>::object_creator
Singleton<T>::create_object;



===============================

xxx.h

class CXXX: public Singleton<CXXX>
{
}


#define qxxx CXXX::GetInstance()

2013-10-29 15:00
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
嗯,其实要解很容易的,只要在变量和函数前加个关键字,表示这个是唯一的就行了,应该不是ms不想解吧,只是可能不是很必要吧

头文件的好处是别人使用起来方便,就像我们用std库一样,从来都是include,也不管它在哪,也不用添加cpp,使用者简单,
当然,我里面其实很复杂,做了很多事,但暴露给外面的,就很简单了
2013-10-29 15:01
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
把定义声明都写在头文件里,不但全局变量有冲突,函数也会有冲突,这时候就要很小心的组合包含,在多文件交叉包含的时候最头疼.就算有#pragma once或者#ifndef这样的保护,也很难避免冲突.
而如果用h+cpp的方式,根本不用担心这种问题,头文件几乎可以随意包含.
2013-10-29 15:03
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
你没有全局变量哦,你这个应该是模板吧
2013-10-29 15:03
0
雪    币: 659
活跃值: (499)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
24
多个函数引用是没关系的,ebx不是用来保存你的全局变量,而是存放你全局变量内存的指针,要获取你的全局变量还必须加上偏移,使用的时候ebx是不变的,所有函数用的ebx都是同一个值,这里ebx就相当于一个特权寄存器一样了。这种方法怕是用汇编写的代码,里面用了ebx这个寄存器,但又不守规则的不保存并恢复,像微软的API里面如果要用ebx是必须前push ebx,用完后再pop ebx的,所以不会改变ebx的值。
2013-10-29 15:04
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
模版应该可行
2013-10-29 15:04
0
游客
登录 | 注册 方可回帖
返回
//