我需要为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
的形式访问输入,或者我什至可以这样做。
答案 0 :(得分:1)
没有任何独立于平台的方式来包装可变参数,因为C没有在不创建va_list
的情况下转发可变参数的功能。
这就是为什么可变参数库函数通常是封装va_list
的函数的包装。例如,Python API包含PyArg_VaParse
,您可以使用va_list
进行调用。它也恰好是PyArg_ArgParse
的实现。
[我添加的修改] 虽然不是一般的解决方案,但特定的解决方案是从DLL访问PyArg_VaParse函数,并将存根输入传递给该函数。然后,存根将按照指定的方式工作,并且可以与它们正在镜像的名义函数具有相同的名称。