函数指针在GCC和Arduino中的不同行为

函数指针在GCC和Arduino中的不同行为,c,gcc,arduino,C,Gcc,Arduino,在我的C程序中,我有一个命令解释器的框架。它在Linux/GCC上运行良好,但在Arduino中它不会返回预期的结果 在下面找到PC代码。我对Arduino做了适当的更改,除了返回字符串外,其他都可以使用,请参见清单中底部的第二行 PC上的C代码工作: #include <stdio.h> char* help(char *s){ char *helpString="This is the help string\n"; return helpString; } type

在我的C程序中,我有一个命令解释器的框架。它在Linux/GCC上运行良好,但在Arduino中它不会返回预期的结果

在下面找到PC代码。我对Arduino做了适当的更改,除了返回字符串外,其他都可以使用,请参见清单中底部的第二行

PC上的C代码工作:

#include <stdio.h>

char* help(char *s){
  char *helpString="This is the help string\n";
  return helpString;
}

typedef struct {
  const char* command;
  char* (*cmdExec)(char *s);
}S_COMMAND;


S_COMMAND cmdTable[]= {
   {"he", help}
};

int main(void){
    char *text;

    printf("\n%s\t",cmdTable[0].command); // returns "he"

    text = (cmdTable[0].cmdExec)("0");
    /* returns help string on PC as expected, but garbage on Arduino */

    printf("\n%s", text);
}
您正在返回一个局部变量-一旦您从函数中超出范围,它就不再存在。它在任何平台上都能工作纯粹是运气,因为一旦它不存在,尝试访问字符串就是未定义的行为


您正在返回一个局部变量-一旦您从函数中超出范围,它就不再存在。它在任何平台上都能工作纯属运气,因为一旦它不存在,尝试访问该字符串就是未定义的行为。

谢谢您的建议。我在Node.JS上修改了如下代码,现在在两个平台上都可以正常工作

int help(char *req, char *res){
  strcpy(res, "This is the help string...\n");
  return 0;
}

typedef struct {
  char* command;
  int (*cmdExec)(char *request, char *result);
}S_COMMAND;

S_COMMAND cmdTable[]= {
  {"he", help}
};

int main(void){
    char text[20];

    cmdTable[0].cmdExec("0", text);
}

谢谢你的建议。我在Node.JS上修改了如下代码,现在在两个平台上都可以正常工作

int help(char *req, char *res){
  strcpy(res, "This is the help string...\n");
  return 0;
}

typedef struct {
  char* command;
  int (*cmdExec)(char *request, char *result);
}S_COMMAND;

S_COMMAND cmdTable[]= {
  {"he", help}
};

int main(void){
    char text[20];

    cmdTable[0].cmdExec("0", text);
}

除了main中缺少return语句外,这是有效的C代码,符合条件的C编译器应该接受它并生成一个可执行文件。特别是,函数指针的使用与当前的问题无关。此外,avr gcc手册未提及任何相关限制。我手头没有Arduino来测试该行为,但是如果avr gcc没有为您显示的输入生成工作代码,那么这表明编译器中存在错误。

这是有效的C代码,除了main中缺少return语句,符合要求的C编译器应该接受它并生成工作的可执行文件。特别是,函数指针的使用与当前的问题无关。此外,avr gcc手册未提及任何相关限制。我手头没有Arduino来测试行为,但是如果avr gcc没有为您显示的输入生成工作代码,那么这表明编译器中存在错误。

这听起来更像是avr哈佛体系结构的问题。可能有一些非标准的调整允许它读取字符串文字。不使用这些旧的8位代码的原因之一。代码在我看来是正确的,但只是为了确保:尝试声明char*helpString=这是帮助字符串\n;作为一个全局变量。也可以尝试直接呼叫帮助text=help0;看看接下来会发生什么。这听起来更像是哈佛大学AVR体系结构的问题。可能有一些非标准的调整允许它读取字符串文字。不使用这些旧的8位代码的原因之一。代码在我看来是正确的,但只是为了确保:尝试声明char*helpString=这是帮助字符串\n;作为一个全局变量。也可以尝试直接呼叫帮助text=help0;然后看看会发生什么。这是帮助字符串\n;是字符串文字,而不是局部变量,因此不应超出范围。如果将其声明为char helpString[]=这是帮助字符串,则它将是局部变量\n;局部变量是不相关的。它在功能上等同于返回这是帮助字符串\n;这是帮助字符串\n;是字符串文字,而不是局部变量,因此不应超出范围。如果将其声明为char helpString[]=这是帮助字符串,则它将是局部变量\n;局部变量是不相关的。它在功能上等同于返回这是帮助字符串\n;注意字符串长度:您破坏了传递的缓冲区。你能把帮助字符串指针放进结构中吗?谢谢,但是这里的缓冲区仅供参考。无论如何,我知道我必须遵守缓冲区的长度。注意字符串的长度:你破坏了你传递的缓冲区。你能把帮助字符串指针放进结构中吗?谢谢,但是这里的缓冲区仅供参考。无论如何,我知道我必须遵守缓冲区长度。