Function Template
Header File
#include "mln_func.h"
The MLN_FUNC macro will generate special function code only when the macro MLN_FUNC_FLAG is defined at compile time; otherwise, it will generate a regular C function.
Module
func
Functions/Macros
mln_func_entry_callback_set
void mln_func_entry_callback_set(mln_func_entry_cb_t cb);
typedef int (*mln_func_entry_cb_t)(void *fptr, const char *file, const char *func, int line, ...);
Description: Set the callback function for the function entry. Description of the parameters and return value of mln_func_entry_cb_t
:
fptr
is a function pointer, which points to the function corresponding tofunc
.file
: The file where the function is located.func
: The name of the function.line
: The line number in the file....
: The variable arguments here are the function arguments of the caller function for this callback function. This parameter only works under C99.- Return value:
<0
indicates that the function call is stopped and returns immediately, meaning the actual function logic will not be executed. Otherwise, the actual function logic will be executed.
Return value: None
mln_func_entry_callback_get
mln_func_entry_cb_t mln_func_entry_callback_get(void);
Description: Get the entry callback function.
Return value: Pointer to the entry function
mln_func_exit_callback_set
void mln_func_exit_callback_set(mln_func_exit_cb_t cb);
typedef void (*mln_func_exit_cb_t)(void *fptr, const char *file, const char *func, int line, void *ret, ...);
Description: Set the callback function for the function exit. Description of the parameters of mln_func_exit_cb_t
:
fptr
is a function pointer, which points to the function corresponding tofunc
.file
: The file where the function is located.func
: The name of the function.line
: The line number in the file.ret
: A pointer to the return value of the function related to the callback. Refer to the example below for usage....
: The variable arguments here are the function arguments of the caller function for this callback function. This parameter only works under C99.
Return value: None
mln_func_exit_callback_get
mln_func_exit_cb_t mln_func_exit_callback_get(void);
Description: Get the exit callback function.
Return value: Pointer to the exit function
MLN_FUNC
MLN_FUNC(scope, ret_type, name, params, args, ...);
Description: Define a function that returns a non-void type. The implementation is to define two functions, one with the name specified by name
, and the other with a name that starts with __mln_func_
followed by the name specified by name
. The first function is just a wrapper, while the second function is the actual function corresponding to the function body represented by ...
. This allows you to call the function in the wrapper and add logic for callback function calls before and after the function call. If the entry callback function returns a value <0
, the __mln_func_xxx
function will not be called, and in this case, the return value of the function name
will be MLN_FUNC_ERROR
.
The parameters of this macro are:
scope
: The scope keyword of the function.ret_type
: The return type of the function.name
: The name of the function.params
: The parameter list of the function, including parameter names and types, enclosed in()
.args
: The argument list of the function, excluding parameter types, enclosed in()
. These arguments are the arguments passed to the real function by the wrapper when calling the real function. The names and order of these arguments should be identical with those inparams
....
: The function body, enclosed in{}
.
Return value: None
MLN_FUNC_VOID
MLN_FUNC_VOID(scope, ret_type, name, params, args, func_body);
Description: Define a function that returns void. The implementation is to define two functions, one with the name specified by name
, and the other with a name that starts with __mln_func_
followed by the name specified by name
. The first function is just a wrapper, while the second function is the actual function corresponding to the function body represented by ...
. This allows you to call the function in the wrapper and add logic for callback function calls before and after the function call. If the entry callback function returns a value <0
, the __mln_func_xxx
function will not be called, and in this case, the return value of the function name
will be MLN_FUNC_ERROR
.
The parameters of this macro are:
scope
: The scope keyword of the function.ret_type
: The return type of the function.name
: The name of the function.params
: The parameter list of the function, including parameter names and types, enclosed in()
.args
: The argument list of the function, excluding parameter types, enclosed in()
. These arguments are the arguments passed to the real function by the wrapper when calling the real function. The names and order of these arguments should be identical with those inparams
....
: The function body, enclosed in{}
.
Return value: None
MLN_FUNC_CUSTOM
MLN_FUNC_CUSTOM(entry, exit, scope, ret_type, name, params, args, ...);
Description: Define a function that returns a non-void type. The implementation is to define two functions, one with the name specified by name
, and the other with a name that starts with __mln_func_
followed by the name specified by name
. The first function is just a wrapper, while the second function is the actual function corresponding to the function body represented by ...
. This allows you to call the function in the wrapper and add logic for callback function calls before and after the function call. If the entry callback function returns a value <0
, the __mln_func_xxx
function will not be called, and in this case, the return value of the function name
will be MLN_FUNC_ERROR
.
The parameters of this macro are:
entry
: The callback function for the function entry.exit
: The callback function for the function exit.scope
: The scope keyword of the function.ret_type
: The return type of the function.name
: The name of the function.params
: The parameter list of the function, including parameter names and types, enclosed in()
.args
: The argument list of the function, excluding parameter types, enclosed in()
. These arguments are the arguments passed to the real function by the wrapper when calling the real function. The names and order of these arguments should be identical with those inparams
....
: The function body, enclosed in{}
.
Return value: None
MLN_FUNC_VOID_CUSTOM
MLN_FUNC_VOID_CUSTOM(entry, exit, scope, ret_type, name, params, args, ...);
Description: Define a function that returns void. The implementation is to define two functions, one with the name specified by name
, and the other with a name that starts with __mln_func_
followed by the name specified by name
. The first function is just a wrapper, while the second function is the actual function corresponding to the function body represented by ...
. This allows you to call the function in the wrapper and add logic for callback function calls before and after the function call. If the entry callback function returns a value <0
, the __mln_func_xxx
function will not be called, and in this case, the return value of the function name
will be MLN_FUNC_ERROR
.
The parameters of this macro are:
entry
: The callback function for the function entry.exit
: The callback function for the function exit.scope
: The scope keyword of the function.ret_type
: The return type of the function.name
: The name of the function.params
: The parameter list of the function, including parameter names and types, enclosed in()
.args
: The argument list of the function, excluding parameter types, enclosed in()
. These arguments are the arguments passed to the real function by the wrapper when calling the real function. The names and order of these arguments should be identical with those inparams
....
: The function body, enclosed in{}
.
Return value: None
Example
//a.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, car, (int *a, int b), (a, b), {
printf("%s\n", __FUNCTION__);
return 100;
})
MLN_FUNC(static, int, bar, (void), (), {
printf("%s\n", __FUNCTION__);
return 0;
})
static int my_entry(void *fptr, const char *file, const char *func, int line, ...)
{
if (!strcmp(func, "bar")) {
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(void *fptr, const char *file, const char *func, int line, void *ret, ...)
{
if (!strcmp(func, "bar"))
return;
#if defined(MLN_C99)
va_list args;
va_start(args, ret);
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
if (ret != NULL)
printf("return value is %d\n", *((int *)ret));
}
int main(void)
{
int a = 1;
mln_func_entry_callback_set(my_entry);
mln_func_exit_callback_set(my_exit);
foo(&a, 2);
car(&a, 3);
return bar();
}
In this example, the MLN_FUNC
is used to define three functions, foo
, bar
, and car
.
Let's first look at the execution under C99, compile at first:
cc -o a a.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon -std=c99 -DMLN_C99 -DMLN_FUNC_FLAG
You will see the following output after running this program:
entry a.c foo 8 1
in __mln_func_foo: 2
exit a.c foo 8 4
entry a.c car 13 4
__mln_func_car
exit a.c car 13 5
return value is 100
bar won't be executed
As explained in the MLN_FUNC
macro, when using this macro to define functions, the actual function will be prefixed with __
, while the original name given will be a wrapper.
Next, let's look at the execution under C89, compile at first:
cc -o a a.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon -DMLN_FUNC_FLAG
You will see the following output after running this program:
entry a.c foo 8
in __mln_func_foo: 1
exit a.c foo 8
entry a.c car 13
__mln_func_car
exit a.c car 13
return value is 100
bar won't be executed
Finally, let's see the effect of not defining the macro MLN_FUNC_FLAG
. Compile it at first:
cc -o a a.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon
You will see the following output after running this program:
in foo: 1
car
bar