使用`char const * str`

时间:2019-11-28 12:46:54

标签: c atmega

设置

#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

1 个答案:

答案 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