首页
社区
课程
招聘
[求助]宏里面还能将宏替换吗?
发表于: 2014-9-12 20:45 6321

[求助]宏里面还能将宏替换吗?

2014-9-12 20:45
6321
我想写这样一个东西:
#define FILENAME MyFile
#define DEFINEDATA(x)    PVOID g_##FILENAME##_##x = 1

//使用:
DEFINEDATA(MyFun);

希望DEFINEDATA能产生一个变量如下:
PVOID g_MyFile_MyFun = 1;

我上面的代码是执行不正确的,结果是定义了一个叫:g_FILENAME_MyFun的变量
FILENAME并未实现替换

尝试这样也不对:
#define DEFINEDATA(x)   DEFINEDATA_(x, FILENAME)
#define DEFINEDATA_(x, y)    PVOID g_##y##_##x

请问应该怎么写?

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

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 229
活跃值: (498)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
##后面的宏是不会展开的
2014-9-12 21:19
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
我其实不是想它在##后在展开,而是在传参数时就展开,这样##后面的是展开后的值了

那如果要实现我想要的功能应该怎么写?
2014-9-15 10:08
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
## 后面的宏 不展开. 我那个 CONNECT 要转换二次(这里其实不用三次)就是要 解决这个问题

让参数在 遇到 ##之前 先展开.

#define CONNECT(a, b) CONNECT1(a, b)
#define CONNECT1(a, b) CONNECT2(a, b)
#define CONNECT2(a, b) a##b

#define FILENAME MyFile
#define DEFINEDATA(x) PVOID CONNECT(CONNECT(CONNECT(g_, FILENAME), _), x) = (PVOID)1234 
int _tmain(int argc, _TCHAR* argv[])
{
    DEFINEDATA(abc);
    printf("%d\n", g_MyFile_abc);
    int a = 1, b = 2;
    char * c = "cccc";
    Logs(a, b);
    return 0;
}
2014-9-17 09:06
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
用函数不好吗
2014-9-17 09:26
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
函数 能定义全局变量吗?
2014-9-19 10:44
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
哦,是的
对了,你那个得到宏参数个数的原理是啥?
看了半天没看懂
2014-9-19 10:51
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这个宏也是从 别人那里看来的.
原理就是 __VA_ARGS__展开后.会 占用 参数的位置. 如果有 __VA_ARGS__ 10个.就占用10个位置
,再展开,输出的就是第11个位置上的那个数字.
#define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _
#define REPEAT_PARAMS(...) (__VA_ARGS__)
#define COUNT_PARMS(...) COUNT_PARMS2 REPEAT_PARAMS(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
    COUNT_PARMS2(A,B,C) => COUNT_PARMS2 ( A,  B,  C, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0)
                        =>              (_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _
                        =>                                                        @  就是这个

2014-9-20 18:35
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
非常谢谢你的解释,我现在明白了,原因在于我一直把_这个当字符理解去了,而没考虑到它是个参数名
2014-9-22 14:32
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
再问一个问题:

#define COUNT_PARMS(...) COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

#define COUNT_PARMS(...) COUNT_PARMS2 REPEAT_PARAMS(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
的本质区别在哪里?

为什么上面的写法就不对?
如:
COUNT_PARMS(xxx,yyy)
上面的返回1,下面的返回就是2
2014-9-22 16:55
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
还有,当调用时不写参数时,得到的参数也为1,导致拼接的东西不对,有好的办法处理不?
2014-9-22 18:30
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
没想到. 也没找到好办法.
当没有参数时,那里还是有一个 ',' .
2014-9-23 00:49
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
第一种写法. __VA_ARGS__没有正确展开.而是被当一个参数了.
2014-9-23 00:51
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
看到网上说GCC下支持##__VA_ARGS__能吃掉前面的,
vs下试了无效
2014-9-23 10:07
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
可惜无法吃掉后面的. 总是有牛人有解决这个的办法.只是还没找到.
2014-9-23 13:17
0
游客
登录 | 注册 方可回帖
返回
//