C语言中的面向切面编程(AOP)_c代码 aop(1)

因此,Melon支持了c99,并利用c99提供的宏特性,实现了将函数模板定义的函数的实参以可变参数的形式传递到入口和出口回调函数中。这就意味着,入口和出口回调函数可以访问函数的参数,并对参数的内容作出修改(主要针对指针指向的内存中的数据)。

这样,就给我们在回调函数中提供了更多的可操作空间。我们可以针对不同的函数,修改其参数值,从而来影响后续函数调用中的执行逻辑。我们也可以利用回调函数的处理结果来决定是否应该调用实际函数(也就是过滤功能)。例如前面的权限验证,我们可以将其大致简化为如下形式:

int entry\_callback(char \*file, char \*func, int line, ...)
{
  va_list args;
  va\_start(args, line);
  int \*id = (int \*)va\_arg(args, int \*);
  va\_end(args);

  return !verify\_identity(id)? -1: 0;
}

void exit\_callback(char \*file, char \*func, int line, ...)
{
  va_list args;
  va\_start(args, line);
  int \*id = (int \*)va\_arg(args, int \*);
  va\_end(args);
  log("%d\n", \*id);
}

void foo(int \*id)
{
  //...
}

int bar(int \*id, int e)
{
  //...
  return 0;
}

这里的代码只是一个示意,后面会给出一个实际可用的示例。

我们可以随意增加函数,这些函数都会利用同一对入口和出口函数来实现身份验证。

示例

下面就给出一个可用的使用函数模板实现AOP的C语言代码。

#include "mln\_func.h"
#include <stdio.h>
#include <string.h>
#if defined(MLN\_C99)
#include <stdarg.h>
#endif

MLN\_FUNC\_VOID(static, void, foo, (int \*a, int b), (a, b), {
    printf("in %s: %d\n", __FUNCTION__, \*a);
    \*a += b;
})

MLN\_FUNC(static, int, bar, (void), (), {
    printf("%s\n", __FUNCTION__);
    return 0;
})

static int my\_entry(const char \*file, const char \*func, int line, ...)
{
    if (strcmp(func, "foo")) {
        printf("%s won't be executed\n", func);
        return -1;
    }

#if defined(MLN\_C99)
    va_list args;
    va\_start(args, line);
    int \*a = (int \*)va\_arg(args, int \*);
    va\_end(args);

    printf("entry %s %s %d %d\n", file, func, line, \*a);
    ++(\*a);
#else
    printf("entry %s %s %d\n", file, func, line);
#endif

    return 0;
}

static void my\_exit(const char \*file, const char \*func, int line, ...)
{
    if (strcmp(func, "foo"))
        return;

#if defined(MLN\_C99)
    va_list args;
    va\_start(args, line);
    int \*a = (int \*)va\_arg(args, int \*);
    va\_end(args);

    printf("exit %s %s %d %d\n", file, func, line, \*a);
#else
    printf("exit %s %s %d\n", file, func, line);
#endif
}

int main(void)
{
    int a = 1;

    mln\_func\_entry\_callback\_set(my_entry);
    mln\_func\_exit\_callback\_set(my_exit);

    foo(&a, 2);
    return bar();
}

这段函数中,我们使用MLN_FUNCMLN_FUNC_VOID来定义了两个函数,即foobar。两个函数的逻辑很简单,就是printf输出当前函数名以及参数值(如果有参数的话)。同时,我们也使用了mln_func_entry_callback_setmln_func_exit_callback_set定义了两个全局回调函数,用来在函数调用开始和结束时调用。

我们可以看到,回调函数中使用strcmp对进入回调的函数做了过滤,仅对foo函数做额外处理。在入口回调中输出函数信息及第一个参数的值,随后修改参数指针指向的内存中的值。在出口回调中输出函数信息和参数值。

我们来编译一下(我们假定这个代码文件名为a.c):

cc -o a a.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon -std=c99 -DMLN\_C99 -DMLN\_FUNC\_FLAG

这里:

  • /usr/local/melon是Melon库的默认安装路径。
  • -std=c99是启用c99。
  • -DMLN_C99是定义一个名为MLN_C99的宏,这个宏用来启用函数模板组件中C99下才有的特性。
  • -DMLN_FUNC_FLAG用来定义一个名为MLN_FUNC_FLAG的宏,这个宏用来启用函数模板功能。是的,如果没有这个宏,上面的那些使用MLN_FUNC定义的函数就是普通的C语言函数,也不会触发入口和出口回调函数的调用。

执行一下看看效果:

entry a.c foo 8 1
in __mln_func_foo: 2
exit a.c foo 8 4
bar won't be executed

可以看到:

为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!

这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。

本份面试集锦涵盖了

  • 174 道运维工程师面试题
  • 128道k8s面试题
  • 108道shell脚本面试题
  • 200道Linux面试题
  • 51道docker面试题
  • 35道Jenkis面试题
  • 78道MongoDB面试题
  • 17道ansible面试题
  • 60道dubbo面试题
  • 53道kafka面试
  • 18道mysql面试题
  • 40道nginx面试题
  • 77道redis面试题
  • 28道zookeeper

总计 1000+ 道面试题, 内容 又全含金量又高

  • 174道运维工程师面试题

1、什么是运维?

2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?

3、现在给你三百台服务器,你怎么对他们进行管理?

4、简述raid0 raid1raid5二种工作模式的工作原理及特点

5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?

6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

7、Tomcat和Resin有什么区别,工作中你怎么选择?

8、什么是中间件?什么是jdk?

9、讲述一下Tomcat8005、8009、8080三个端口的含义?

10、什么叫CDN?

11、什么叫网站灰度发布?

12、简述DNS进行域名解析的过程?

13、RabbitMQ是什么东西?

14、讲一下Keepalived的工作原理?

15、讲述一下LVS三种模式的工作过程?

16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

17、如何重置mysql root密码?

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值