使用var_arg为函数调用传递参数
Using var_arg to pass parameters for function calls
我正在编写一个适配器来组合两个API(一个在C中,另一个在C++中)。如果在一个API上调用函数,我需要将调用方ID和函数的参数传递给适配器,并使用传递的信息调用相应的函数。
现在,它们通常不能直接映射,因为一个接口需要C++编译,而名称篡改会破坏另一个接口,所以这就是我首先使用一组适配器的原因。
由于参数的数量不同,我查找了可变函数,发现这个想法非常有用,但我只在POD上操作,每次调用都必须处理结构、枚举和许多不同的参数,这些参数可能需要放回结构中,然后再将其提供给目标函数。
我偶然发现的每一个例子都要简单得多,主要涉及算术运算,比如求和、求最大数或打印。主要使用var_list上的for循环完成。
也许我被这个想法卡住了,它根本不起作用,但我只是好奇。。。
假设我想将列表中的参数分配给我的目标函数参数(传递的参数的顺序是正确的),有什么好方法?
BOOL Some_Function(
/* in */ CallerId *pObjectId,
/* in */ someDataType argument1 )
{
BOOL ret = Adapter_Call(pFunction, pObjectId, argument1);
return ret;
}
所以一旦我找到合适的适配器,我就想做
BOOL Adapter_Call(*pFunction, *pObjectId, argument1, ...)
{
va_list args;
va_start(args, argument1);
/*go over list and do `var_list[i] = pFunctionArgList[i]` which is
of whatever type so I can use it as input for my function */
va_end(args);
pObjectId.pFunction(arg1,...,argn);
}
我可以访问函数的输入参数来执行这样的分配吗?以前有人做过这样的事吗?我的想法有概念上的错误吗?
我在网上找到的只有这个,http://www.drdobbs.com/cpp/extracting-function-parameter-and-return/240000586but由于使用了模板,我不确定它是否会产生另一个问题,因此最终为每个函数调用实现一个适配器可能会更简单。
SO搜索只返回以下内容:运行时动态函数调用(va_list)
首先,您应该听取Kerrek关于extern "C"
的建议。这是C++提供标识符C链接的机制,这意味着C++编译器不会损坏名称。
有时,和适配器仍然需要为C++接口编写,因为它处理的对象不映射到C POD。因此,适配器为C接口提供了一个POD或不透明指针类型来操作,但该接口的实现将其转换为C++对象或引用,然后调用C++接口。例如,假设您想为C++std::map<int, void *>
提供一个C接口,那么在C和C++中会有一个公共头文件,其中包含:
#ifdef __cplusplus
extern "C" {
#endif
struct c_map_int_ptr;
// ...
// return -1 on failure, otherwise 0, and *data is populated with result
int c_map_int_ptr_find (struct c_map_int_ptr *, int key, void **data);
#ifdef __cplusplus
}
#endif
然后,C++代码可以实现如下功能:
typedef std::map<int, void *> map_int_ptr;
int c_map_int_ptr_find (struct c_map_int_ptr *cmap, int key, void **data) {
map_int_ptr &map = *static_cast<map_int_ptr *>(cmap);
map_int_ptr::iterator i = map.find(key);
if (i != map.end()) {
*data = i->second;
return 0;
}
return -1;
}
因此,不需要通过变量参数适配器传递通过C接口传递的参数。因此,C++代码不需要从变量参数列表中梳理出参数。C代码直接调用C++代码,C++代码知道如何处理参数。
我想,如果您试图通过解析C++代码来实现某种自动化的C适配器代码生成器,您可能会认为使用变量自变量将提供一种常规机制,在生成的C代码接口和调用原始C++接口的生成的C++适配器代码之间通信自变量。对于这样的场景,上面例子的代码看起来像这样:
// C interface
typedef struct c_map_int_ptr c_map_int_ptr;
typedef struct c_map_int_ptr_iterator c_map_int_ptr_iterator;
//...
c_map_int_ptr_iterator c_map_int_ptr_find (c_map_int_ptr *map, int key) {
c_map_int_ptr_iterator result;
cpp_map_int_ptr_adapter(__func__, map, key, &result);
return result;
}
// C++ code:
struct cpp_adapter {
virtual ~cpp_adapter () {}
virtual void execute (va_list) {}
};
void cpp_map_int_ptr_adapter(const char *func, ...) {
va_list ap;
va_start(ap, func);
cpp_map_int_ptr_adapter_method_lookup(func).execute(ap);
va_end(ap);
}
//...
struct cpp_map_int_ptr_find_adapter : cpp_adapter {
void execute (va_list ap) {
map_int_ptr *map = va_arg(ap, map_int_ptr *);
int key = va_arg(ap, int);
c_map_int_ptr_iterator *c_iter = va_arg(ap, c_map_int_ptr_iterator *);
map_int_ptr::iterator i = map->find(key);
//...transfer result to c_iter
}
};
其中cpp_map_int_ptr_adapter_method_lookup()
基于表查找返回适当的cpp_adapter
实例。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何用参数值调用函数(仅在运行时已知)
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 函数调用C++中的参数太少
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 根据参数数调用 mixin 基类的构造函数
- 使用并行参数向量调用元素向量的成员函数
- uncrustify:如何将多行 C 函数调用的参数组合到一行上?
- 函数调用中的参数过多
- 使用显式模板参数列表和 [temp.arg.explicit]/3 的函数调用的演绎失败
- 可变参数模板函数:调用没有匹配函数,std::endl
- 对可变参数函数的递归调用的链接器错误
- 宏函数调用缺少参数警告,即使给定了参数
- 具有不同类型的可选参数的调用方函数
- C++ 使函数调用依赖于模板参数
- 迭代器的模板参数:函数在调用时推断类型?
- 如果我提前将参数声明为变量而不是将它们内联写入函数调用,那有什么区别(在内存方面)?
- 链接可变参数函数调用
- 递归可变参数函数调用对简单 if.else 语句的性能