在微控制器的this Python implementation中,他们使用C-macro,如下所示:
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class NoEndpointFoundEndpointMapping implements EndpointMapping {
@Override
public EndpointInvocationChain getEndpoint(MessageContext messageContext) throws Exception {
throw new MyCustomException(...);
}
}
使用:
MP_ROM_QSTR(MP_QSTR_mem16)
和
#define MP_ROM_QSTR(q) MP_OBJ_NEW_QSTR(q)
我的问题是:#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
似乎从未被定义过!
那么,这是如何工作的?
答案 0 :(得分:2)
宏可以像任何宏一样通过文本替换来完成。原始代码
MP_ROM_QSTR(MP_QSTR_mem16)
分两步替换,首先将其缩小为
MP_OBJ_NEW_QSTR(MP_QSTR_mem16)
减少到
((mp_obj_t)((((mp_uint_t)(MP_QSTR_mem16)) << 2) | 2))
最终传递给C / C ++编译器。
当你说术语MP_QSTR_mem16
是&#34;从未定义&#34;那可能是真的。它的定义与否与此宏的使用无关。此宏不应该是术语MP_QSTR_mem16
的定义或声明,而是该术语的 use
宏生成一个表达式,将MP_QSTR_mem16
强制转换为类型mp_uint_t
,然后将结果值左移两位,二进制结果值2
和将结果转换为类型mp_obj_t
。这些都没有定义或声明它开始的值。
您可能想知道值MP_QSTR_mem16
应该来自何处。
修改
在查看来源后,您指出我也无法找到MP_QSTR_mem16
的声明。在我看来,通过连接一些字符串,术语说明符MP_QSTR_mem16
是创建。这可以使用##
运算符在C / C ++预处理器中完成。如果您在代码中搜索MP_QSTR_ ##
,则会发现类似这样的事件:
./micropython-master/teensy/mk20dx256_prefix.c: .name = MP_QSTR_ ## p_port ## p_pin, \
实际上,实际定义MP_QSTR_mem16
的位置也可能如下所示:
#define FOO(x) MP_QSTR_ ## x
(......以后,某处...)
int FOO(mem16);
但是尽管在源头搜索了一段时间我却没有找到这样的地方。它可以非常隐蔽地隐藏在宏观逻辑中。找到该位置的合适方法可以是调整编译器以写出预处理器的结果;在这个你应该能够找到它(但这远远超出了这个问题的主题,所以如果你在使用这种方法时遇到问题,请提出另一个问题)。