【问题标题】:Passing variables to another variadic function [Experts Edition]将变量传递给另一个可变参数函数 [专家版]
【发布时间】:2018-07-23 16:00:03
【问题描述】:

我需要为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;
}

所以,这个技巧是不能连续做两次的。所以我被困住了。 第二个输入是格式字符串,因此可以根据字符串的长度轻松确定参数的数量。那么,我能否以voids 的形式访问变量输入,然后根据参数的数量将它们传递给单独的调用。我可以使用基于参数数量的开关,然后调用myPyArg_ParseTuple(inp1, inp2, arg1)myPyArg_ParseTuple(inp1, inp2, arg1, arg2) 等。

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

【问题讨论】:

    标签: c function variadic


    【解决方案1】:

    没有独立于平台的方法来包装可变参数函数,因为 C 没有在不创建 va_list 的情况下转发可变参数参数的工具。

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

    [我添加的编辑] 虽然不是通用解决方案,但具体解决方案是改为从 DLL 访问 PyArg_VaParse 函数并将存根输入传递给该函数。然后存根按指定工作,并且可以与它们所镜像的标称函数具有相同的名称。

    【讨论】:

    • 我注意到,如果我将 myPyArg_ArgParse 指向 PyArg_VaParse,那么代码将按预期工作。这使我可以在顶级代码中保留 Python 调用的名义名称。
    • 就个人而言,我会打电话给myPyArg_ArgParse 更具描述性的名称,例如my_VaParse。但是,是的,这是基本的想法。
    • 是的,我称之为 myPyArg_VaParse。
    猜你喜欢
    • 2018-10-22
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 2011-04-01
    相关资源
    最近更新 更多