单片机回调函数请教:怎样获取其它文件的函数的地址
//interrupt.h 文件,由甲方编写#ifndef INTERRUPT_H
#define INTERRUPT_H
void interrupt(void);
void add(void);
#endif//interrupt.c 文件,由甲方编写
#include "interrupt.h"
void interrupt(void)
{
void (*func)();
func=add;
func();
add();
}//main.c文件,由乙方编写
#include <stdio.h>
#include <stdlib.h>
#include "interrupt.h"
//==============================
void add(void)
{
static int test;
test++;
printf("test=%d\n",test);
}
//==============================
int main(void)
{
interrupt();
return 0;
}
//end运行结果:
test=1
test=2
请教:如果甲方不知道乙方的函数名是 add,那么,甲方怎样才能运行乙方的add函数,就是说,甲方怎样获取乙方的add函数的地址? 本帖最后由 panxiaoyi 于 2023-3-27 22:45 编辑
//函数 interrupt() 是模拟单片机中断运行函数 ,是由甲方编写的底层函数
//甲方的目的是要在中断里面调用乙方的用户层面的函数
//我现在遇到的问题是:甲方是底层开发,乙方是用户层开发,所以,甲方不知道用户函数名叫add
//所以,如果甲方没有下面两条语句 那么,甲方是怎样去获取乙方的函数的地址呢
func=add;
void add(void);
//我看了很多网上的回调函数的例子,这些例子要么是在同一个C文件内完成,要么非常的复杂,看不懂。
//请教,谢谢
把interrupt()函数写成需要传入函数指针参数就可以啊。 本帖最后由 computer00 于 2023-3-28 19:57 编辑
可以让甲方给你增加一个注册中断回调函数的接口,等中断发生时,就可以回调到乙方定义的函数了。例如:
/////////////////////////////////// interrupt.c ///////////////////////////////////////
typedef int (*IsrCallbackFuncType)(int id, void *data);
#define CONFIG_MAX_INTS 8
static IsrCallbackFuncType sgIsrCbTab;
static void* sgIsrCbData;
int registerInterruptCallback(int intId, IsrCallbackFuncType callbackFunc, void *pData) {
if (intId < 0 || intId >= CONFIG_MAX_INTS) {
return -1;
}
sgIsrCbTab = callbackFunc;
sgIsrCbData = pData;
return 0;
}
void interrupt(void) {
int id = 0;
// do something, eg. id = getIntId();
if (sgIsrCbTab != 0) {
int ret = sgIsrCbTab(id, sgIsrCbData);
}
// do something, eg. clean int flag
}
//////////////////////////////////////////////// main.c ////////////////////////////////////////////
typedef int (*IsrCallbackFuncType)(int id, void *data);
int registerInterruptCallback(int intId, IsrCallbackFuncType callbackFunc, void *pData);
int timerIsrCb(int id, void *data) {
printf("%s, %d: id = %d, data = '%s'\n", __FUNCTION__, __LINE__, id, (char *)data);
}
void main(void) {
char buffer = {"Hello LSTM"};
int ret = registerInterruptCallback(0, timerIsrCb, (void *)buffer);
}
这样做有什么好处,为什么要分开两边写,还不能沟通
一般是建个数组,数组中存放函数地址,数组使用绝对定位就可以了 正常库一般会有头文件的啊,头文件里面有函数名,库里面是函数实现,调用要看头文件里面的函数调用,不是瞎蒙吧。不同层之间,你要有头文件,不然你怎么知道哪个函数符合要求可以用。。。。乱写一通?? 不知道函数名字,怎么把函数指针指向函数入口地址,
除非强制定义地址,然后调用,
多谢大家,特别是 5楼 computer00,我会好好的学习的,就是不知道能不能看的懂,后面会继续反馈的 gyh974 发表于 2023-3-28 11:55
这样做有什么好处,为什么要分开两边写,还不能沟通
回复6楼,因为我现在在写小工程,渐渐的发现,工程全局变量真的越少越好,多了就容易引起逻辑混乱,查错困难。后来又发现,硬件底层很多时候需要调用应用层的函数,于是,就学习到了回调函数,现在就卡在这里了。
需要说明的是,我现在写的基本上都是8位机的代码,但是工程很多,需要经常移植,所以,上面的问题就很自然的浮出水面了 下面是我的理解,如果大家有空,请帮我看看是否正确,谢谢
//interrupt.h 文件,由甲方编写
#ifndef INTERRUPT_H
#define INTERRUPT_H
void interrupt(void);
void CallBackRegister(void(*func2)());
#endif
//interrupt.c //模拟单片机中断文件,由甲方编写
#include "interrupt.h"
static void (*func3)(); //定义函数指针变量(产生代码,非声明)
//==============================
void CallBackRegister(void(*func2)()) {//定义注册函数,给乙方使用
func3 = func2; //记忆乙方的函数地址,这就是回调函数注册
}
//==============================
void interrupt(void) {
void (*func)(); //定义局部函数指针变量
func = func3; //将上面注册进来的地址赋值测试
func(); //通过指针,运行被调用的函数
add(); //普通方式,直接调用函数
}
//==============================
/*
请教:
1:
请问,这里的甲方是不是(必须)要定义一个本文件的全局函数指针变量 func3
然后,注册函数 CallBackRegister 和 中断函数 interrupt 共用这个变量,
这样甲方才能"知道"和"运行"乙方传进来的函数
2:
我在代码上的注释是否正确,因为它代表了我的理解。谢谢
*/
//main.c //main.c 文件,由乙方编写
#include <stdio.h>
#include "interrupt.h"
//==============================
void add(void) { //定义被调用的函数,这个函数叫“回调函数”
static int test; //测试变量
test++; //变量++
printf("test=%d\n", test); //输出显示
}
//==============================
int main(void) { //用户(乙方)的主函数
CallBackRegister(add); //注册回调函数,就是把add函数的地址告诉甲方
interrupt(); //模拟单片机进入中断服务函数
return 0;
}
//end
代码截图
页:
[1]