设置
#define functionA(str) functionB(PSTR(str))
void functionB(char const* str) { ... something, e.g. print str... }
void functionC(char const* str) {
functionA("Hello World"); // this one work
functionA(str); // however this doesn't work
}
问题
我有一个函数function B
,我尝试使用它。如果我简单地用"some string"
来调用它,那就完美了。但是,如果我尝试在functionC
中使用参数str
进行调用,则编译器将返回错误“无效的初始化程序”和消息“正在扩展宏PSTR”。我该怎么解决,我的问题出在哪里?
编辑-其他信息
程序在AT Mega上运行,PSTR也来自AT-Mega
#define PSTR(s) ((const PROGMEM char *)(s))
#else /* !DOXYGEN */
/* The real thing. */
# define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
#endif /* DOXYGEN */
#define PROGMEM __ATTR_PROGMEM__
#ifndef __ATTR_PROGMEM__
#define __ATTR_PROGMEM__ __attribute__((__progmem__))
#endif
答案 0 :(得分:3)
您不能混合使用程序空间和常规字符串,因为它们存储在不同的存储空间中。 AVR体系结构将数据和程序存储器分开,常规变量/字符串存储在数据存储器(RAM)中。但是,由于这些设备上的RAM通常非常有限,因此可以在程序空间中存储常量数据(例如字符串),以避免使用RAM。提供PSTR
宏可用于字符串文字。
functionA(str)
出错的原因很简单,就是它最终将宏用作PSTR(str)
,而PSTR
仅适用于字符串文字,因为您不能将数据放在程序空间中运行。但也请注意,PSTR("Hello world")
工作时,functionB
必须特别期待程序空间字符串,否则它将把指针当作指向RAM的指针(不是)。
要使用程序空间字符串,您可以使用PSTR
作为参数并使用pgm_*
函数/宏(例如pgm_read_byte
)来处理它,或者首先复制PSTR
到RAM(例如strcpy_P
),然后将其传递给需要常规字符串的函数。参见avr/pgmspace.h
。