我试图在EM_ASM样式的宏中声明一个多元素数组。当我使用普通的旧EM_ASM时,这很好用:
EM_ASM({var a = [1,2];});
但是,在任何返回值的EM_ASM样式宏中执行此操作似乎会使编译器感到困惑。
例如:
EM_ASM_INT_V({var a = [1,2]; return 1;});
给我这些错误:
错误:为类似函数的宏提供了太多参数 调用
test.cc:4:3:注意:不能在宏参数的开头使用初始化列表
test.cc:4:3:错误:使用未声明的标识符' EM_ASM_INT_V'
EM_ASM_INT
,EM_ASM_DOUBLE
和EM_ASM_DOUBLE_V
也是如此(无论我是否向他们提供适当的参数并返回)。如果我声明一个1元素数组:
EM_ASM_INT_V({var a = [1]; return 1;});
一切都很好。使用大括号括起来的Javascript对象也会发生这种情况 - 单个元素(例如{val1: 1}
)很好,但不止于此(例如{val1: 1, val2: 2}
)会给我同样的错误。
我目前的解决方法是单独将其他元素推送到数组:
EM_ASM_INT_V({var a = [1];
a.push(2);
return 1;});
这很有效,但它非常笨重。
我查看了Emscripten github页面上的相关问题,但无法找到。我做错了什么,或者这是一个错误?任何人都有更好的解决方法吗?
答案 0 :(得分:1)
我认为问题与宏调用中的逗号有关。逗号在括号内被忽略,但不在括号,括号或尖括号中,因此它将您的第一个参数拆分为两个:{var a = [1
和2]; return 1;}
,这显然是有问题的。
我没有看过EM_ASM的定义,但由于它只期望一个参数,我的猜测是,如果它不止一个,它会自动用逗号粘在一起。但是,其他EM_ASM_ *宏不知道期望多少个参数,所以他们不能这样做。
至于修复,通常可以包括额外的括号。对于您的示例,您应该能够使用:
EM_ASM_INT_V({var a = ([1,2]); return 1;});
圆括号不会伤害任何东西,但会保持宏观参数粘合在一起(有时它不是那么容易,但通常是这样)。
我知道在预处理器规范中修复这个问题已经很长一段时间了 - 希望有一天它会发生。当在宏调用中包含模板时,它变得特别烦人,因为在这些情况下,没有简单的方法来包围括号中的所有内容。
编辑:我检查了EM_ASM定义,实际上它是一个可变参数宏,它将参数粘合在一起。