将变量传递给另一个可变参数函数[专家版]

时间:2018-07-23 16:00:03

标签: c function variadic

我需要为dll中现有的可变参数编写一个存根。所以我做了名义上建议的事情:

myPyArg_ParseTuple = (void *)GetProcAddress(dll, "PyArg_ParseTuple");

int PyArg_ParseTuple(PyObject *inp1, const char *inp2, ...)
{
    int ret = 0;
    static va_list args;
    va_start(args, inp2);
    ret = myPyArg_ParseTuple(inp1, inp2, args);
    va_end(args);
    return ret;
}

很好,对吧?好吧,不。因为事实证明myPyArg_ParseTuple指向的外部代码具有相同的作用:

[Source code of call in the .dll]

PyArg_ParseTuple(PyObject *args, const char *format, ...)
{
    int retval;
    va_list va;

    va_start(va, format);
    retval = vgetargs1(args, format, &va, 0);
    va_end(va);
    return retval;
}

因此,这种技巧是人们不能连续两次做的事情。所以我被困住了。 第二个输入是格式字符串,因此可以根据字符串的长度轻松确定参数的数量。因此,我可以根据参数的数量将变量输入全部作为void进行访问,然后将它们传递到单独的调用中。我可以根据参数数量使用开关,然后调用myPyArg_ParseTuple(inp1, inp2, arg1)myPyArg_ParseTuple(inp1, inp2, arg1, arg2)等。

我不清楚如何以void的形式访问输入,或者我什至可以这样做。

1 个答案:

答案 0 :(得分:1)

没有任何独立于平台的方式来包装可变参数,因为C没有在不创建va_list的情况下转发可变参数的功能。

这就是为什么可变参数库函数通常是封装va_list的函数的包装。例如,Python API包含PyArg_VaParse,您可以使用va_list进行调用。它也恰好是PyArg_ArgParse的实现。

[我添加的修改] 虽然不是一般的解决方案,但特定的解决方案是从DLL访问PyArg_VaParse函数,并将存根输入传递给该函数。然后,存根将按照指定的方式工作,并且可以与它们正在镜像的名义函数具有相同的名称。