在keil里面变异出现这样的情况,是什么错误,该怎么改正

compiling ni.c...
NI.C(174): error C212: indirect call: parameters do not fit within registers
NI.C(229): error C212: indirect call: parameters do not fit within registers

这是174行的程序:
if( parser->handleDataValue ) {
parser->handleDataValue( 0, PARSER_CODE_RAW_SIGNAL, 2,
parser->payload,
parser->customData );

看你的信息,你那个是在NI.c文件里,也就是说,你的是C语言文件?
但是你有这么一句:
parser->handleDataValue( 0, PARSER_CODE_RAW_SIGNAL, 2,
parser->payload,
parser->customData
);
显而易见,你的那个Parser是一个结构体的指针,而你的这个结构体里有函数:
handleDataValue(,,,)

是这样的,C语言里,结构体是不允许有函数的,C语言的结构体里不允许有函数的存在,C++里可以,C语言不行.
温馨提示:答案为网友推荐,仅供参考
第1个回答  2017-09-10
C语言结构体里面可以使用函数啊,只需要在结构体里面申明的是函数指针就可以了啊
第2个回答  2013-01-26
你的C语言没学好,C语言结构体不允许使用函数.
第3个回答  2018-01-30
上面说结构体中不能使用函数指针的是菜鸟中的菜鸟,51不是基于堆栈架构的,所以有一些参数是无法通过寄存器传递的(51的传参全部有寄存器完成),正常C语言调用是讲参数压入堆栈,正是因为这些区别,所以我们需要对函数进行修改,最简单的在结尾加可重入标识,让keil使用模拟堆栈传参。
uint8_t (*dht22_msg_cb)(dht22_t *dht, uint8_t msg, uint8_t arg_int, void *arg_ptr) reentrant;//由于51不是堆栈架构,所以,这里有一部分参数不能由于R0-R9进行传递,而需要使用模拟堆栈
还有几种情况,例如
void (*p)(void *a,void *b)//这原本是不能正常工作的会报错,报错就是楼主遇到的,怎么改,讲这个指针类型改成内存属性
void (*p) (void xdata *, void xdata *);

另外就是传递的参数过多,超过了寄存器的使用(不一定报错),但是会异常,这里还有一个调用深度的问题,例如我有很多层a调用b,b调用c,,,这样的,如果都不传参,一般没问题,如果传参数,你就要注意了,如果没有使用模拟堆栈,很有可能你本来a传递进两个参数p,q。。后面调用完后面一系列函数之后p,q会变掉,这是由于编译器没寄存器可用的时候使用了和p,q同一个寄存器导致的,文字描述可能有些不够详细,不过我想说,中国学生,老师,普遍的编程水平不高,在职工程师我不清楚,就我的学习经历而言,像此类问题,多google,看不懂用Chrome网页翻译,另外,单片机编程不要太过于苛求外设的驱动,应该注重思想,像结构体中使用函数指针是一个很重要的开始,这可以实现诸如回调机制,面向对象机制,消息机制,等。单片你裸机编程中,有一个很受用的架构叫做以时基和消息驱动的单片机架构(这本书也是国外的),这也是操作系统的基础,好了就说这么多了。
第4个回答  2013-02-02
又是一个新手