如何使用LD_PRELOAD包装可变参数函数?

时间:2018-08-01 06:08:30

标签: c variadic-functions dynamic-linking ld-preload dlsym

我必须对以下格式的可变参数执行动态链接:

int foo(char *args, const char *f, ...)

这里参数的数量是可变的。 我想要实现的是我想将获得的参数传递给我使用dlsym解决的原始函数。 如果我不传递所有参数,则会不断出现细分错误。 预先感谢。

3 个答案:

答案 0 :(得分:4)

我认为您的问题与LD_PRELOAD或dlopen / dlsym无关:您只是想从可变函数调用可变函数,例如:

int printf (const char *fmt, ...) {
    return fprintf (stdout, fmt, my_variadic_parameters);
}

据我所知,这是不可能的,但是在精心设计的库(显然是其中的少数)中,每个可变参数函数都有一个使用va_list参数的对应函数,例如printf和vprintf,fprintf和vfprintf:

int printf (const char *fmt, ...) {
    va_list ap;
    int retval;

    va_start (ap, fmt);
    retval= vfprintf (stdout, fmt, ap);
    va_end (ap);
    return retval;
}

int vmyprintf (const char *fmt, va_list pap) {
    va_list ap;
    int retval;

    va_copy (ap, pap);
    retval= vfprintf (stdout, fmt, ap);
    va_end (ap);
    return retval;
}

因此,您应该要求'foo'的创建者创建一个'vfoo':

int vfoo (char *args, const char *f, va_list v)

答案 1 :(得分:1)

看看for,该手册页中有一个非常简洁的示例。

您可以像对待任何其他函数指针一样对待dlsym符号地址。

va_args背后的基本概念是在循环中使用控制变量,通常是man va_start样式格式的字符串,可以对其进行解析以确定何时退出调用框架构建循环。对于您的ankit,在构建printf时,需要采用某种形式“是否在调用框架中放置另一个参数”。基本上是va_start va_arg ... va_end。

再次,最好用代码解释,并且手册页上有一个很好的例子。

答案 2 :(得分:0)

给予

new_issue

int foo(char *args, const char *f, ...) args提供的信息应该告诉您调用方已将多少种类型的参数作为可变参数传递给您。

如何如何提供此信息取决于f的实现,因此请参见foo文档。

一个很好的例子是foo(),从可变参数中接收的所有信息都可以从第一个参数(非可变格式“字符串”)中进行解析。

如果您未能对此有所了解,就会迷路。在C语言中,没有 no 通用的“内置”方式来收集传递的可变参数的数量和类型。