正文
1、简单模拟委托
//C语言简单模拟委托
//需要用的指针函数。通过用指针函数作为地址接收函数地址,以达到委托其他函数实现某方法的目的。
#include <stdio.h>
typedef void(* fun)(); //typedef 把void(*)()类型重命名为fun
void func(fun); // 被调函数
void func_1(); // 回调函数1
void func_2(); // 回调函数2
int main() // 主函数用做主调函数
{
func(func_1);
fun f = func_2;
f();
func(func_1);
func(func_2);
getchar();
return ;
}
void func(fun f) //fun f为地址,fun * f为f指向的地址的量或者其他
{
printf("func\n");
if (f != NULL)
{
f();
}
}
void func_1()
{
printf("func_1\n");
}
void func_2()
{
printf("func_2\n");
}
/*
func
func_1
func_2
func
func_1
func
func_2
*/
2、简单模拟反射
(1)简单模拟反射
语言的反射机制,简单来说,就是可以通过字符串型获取对应的类或者函数。下面,用C来简单模拟反射:
#include <stdio.h>
#include <string.h>
typedef void (*callback)(void);
typedef struct {
const char *name;
callback fn;
}callback_t;
void f0();
void f1();
callback_t callbacks[] = {
{"cmd0", f0},
{"cmd1", f1},
};
void f0() // 回调函数
{
printf("cmd0");
}
void f1() // 回调函数1
{
printf("cmd1");
}
void do_callback(const char *name)
{
size_t i;
for (i = ; i < sizeof(callbacks) / sizeof(callbacks[]); i++) {
if (!strcmp(callbacks[i].name, name)) {
callbacks[i].fn();
}
}
}
int main()
{
do_callback("cmd1");
getchar();
return ;
}
(2)利用自定义段
// https://www.bejson.com/runcode/c920/
#include <stdio.h>
#define SEC __attribute__((__section__("ss"), aligned(sizeof(void*))))
void func_1 (int a, int b)
{
printf("%s %d %d\n", __func__, __LINE__, a+b);
}
void func_2 (int a, int b)
{
printf("%s %d %d\n", __func__, __LINE__, a*b);
}
// 编译器会自动提供__start_ss,__stop_ss标志段ss的起止地址
extern size_t __start_ss;
extern size_t __stop_ss;
typedef struct {
void (*p)(int, int);
} node_t;
// 结构体变量a位于自定义段ss
SEC node_t a = {
.p = func_1,
};
SEC node_t b = {
.p = func_2,
};
int main(int argc, char **argv)
{
int a = 3, b = 4;
node_t *p;
// 遍历段ss,执行node_t结构中的p指向的函数
for (p = (node_t *)&__start_ss; p < (node_t *)&__stop_ss;p++) {
p->p(a, b);
a+=1;b+=2;
}
}
/*
func_1 6 7
func_2 10 24
*/