如何用C语言截取或包装传递给API接口的函数指针
我有一个场景,我需要用C语言包装一些函数。基本上,我需要在函数之前添加一些信息,以便我们知道何时调用它以及其他调试和异步流信息 我可以使用上面提到的wrap选项包装同步呼叫 但是,有没有一种方法可以将回调封装在GCC、LD或sharedlibraries中,并将其传递给函数 我想到的一个选项是存储回调并用另一个函数重写它如何用C语言截取或包装传递给API接口的函数指针,c,C,我有一个场景,我需要用C语言包装一些函数。基本上,我需要在函数之前添加一些信息,以便我们知道何时调用它以及其他调试和异步流信息 我可以使用上面提到的wrap选项包装同步呼叫 但是,有没有一种方法可以将回调封装在GCC、LD或sharedlibraries中,并将其传递给函数 我想到的一个选项是存储回调并用另一个函数重写它 有没有其他解决方案不需要存储和操作就可以更有效地执行此操作?您可以执行与链接的文章相同的操作。要包装malloc: // wrap.h #define malloc(N) w
有没有其他解决方案不需要存储和操作就可以更有效地执行此操作?您可以执行与链接的文章相同的操作。要包装malloc:
// wrap.h
#define malloc(N) wrapped_malloc(N)
void *wrapped_malloc(size_t n);
// wrap.c
#include "wrap.h"
#undef malloc
void *wrapped_malloc(size_t n) {
printf("called malloc\n");
return malloc(n);
}
// mycode.c
#include "wrap.h"
...
void *p = malloc(42);
...
执行时打印“称为malloc”
或者我误解了你的问题。如果是,请举例说明
添加
与您使用的术语相反,回调和异步执行之间没有内在的联系。例如,libpng很好地利用了回调
但是,由于您可能对线程管理调用感兴趣,让我们总结一下:
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
为此,我们定义:
// wrap.h
#define pthread_create(Thread, Attr, StartRoutine, Arg) \
wrapped_pthread_create(Thread, Attr, StartRoutine, Arg)
int wrapped_pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
然后:
非常感谢您的支持。假设我的库的公共接口是:API_接口(int size,int(*fn)(int));现在,如果我必须包装正在传递的回调,该怎么做。对于同步APi,就像malloc发布的东西一样,只考虑APi的异步registerration,如果我必须知道何时调用CB,并且我必须打印一些参数信息如何执行,我不知道如何执行。如果你有任何信息让我知道,怎么办。Thanks@yathish看到新的补充非常感谢你的信息基因,将尝试回来,
// wrap.c
#include "wrap.h"
#undef pthread_create
// __thread is gcc's thread local storage class keyword.
// If you're using a different compiler, adjust accordingly.
static __thread void *(*captured_start_routine)(void*);
static void *wrapped_start_routine(void *arg) {
printf("called start routine\n");
return captured_start_routine(arg);
}
int wrapped_pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg) {
captured_start_routine = start_routine;
printf("called pthread_create\n");
return pthread_create(thread, attr, wrapped_start_routine, arg);
}