您现在的位置是:首页 >其他 >【trt_infer】 日志网站首页其他
【trt_infer】 日志
简介TensorRT部署封装
C++ 可变长参数
参考:
- https://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html
1. C/C++语言中函数传递参数时的基本原理
在C/C++中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表如:
void foo(...);
void foo(pram_list, ...);
参数存放在内存的堆栈段中,在执行函数的时候,从最后一个入栈,因此栈底高地址,栈顶低地址。如:
void func(int x, float y, char z);
调用函数是,实参 z 先入栈,因此在内存中变量的存放顺序为 x, y, z. 因此理论上说:只要探测到任意一个变量的地址,并且知道其他变量类型,通过指针移位操作,可以找到其他所有的输入变量
2. 可变长参数相关宏
2.1 导入头文件:
#include <stdarg.h>
2.2 相关宏定义:
typedef char* va_list;
void va_start(va_list ap, prev_param); /*ANSI version*/
type va_arg(va_list ap, type);
void va_end(va_list, ap);
- va_list 是一个字符指针,可以理解为指向当前参数的一个指针,取参必须通过这个指针进行。
2.3 可变长参数读取的一般步骤
- 在调用参数表之前,定义一个 va_list 类型的变量。
va_list ap;
- 对ap 进行初始化,让它指向可变参数表里面的第一个参数,这是通过 va_start 来实现的,第一个参数是 ap 本身,第二个参数时在变参表前面紧挨的一个变量,即 “…” 之前的第一个参数。
// void foo(int arg1, int arg2, ...)
va_start(ap, arg2);
- 获取参数。调用 va_arg, 它的第一个参数是 ap ,第二个参数是要获取参数的指定类型,然后返回这个指定类型的值,并且把 ap 的位置指向变参表的下一个变量位置。
char para = va_arg( argp, char);
- 关闭 ap 指针。 在获取所有的参数之后,有必要将这个 ap指针关掉,以免发送危险。
void va_end ( va_list ap );
一个完整的案例:
#include <iostream>
#include <stdarg.h>
std::string format(const char* fmt, ...) {
va_list vl;
va_start(vl, fmt);
char buffer[2048];
vsnprintf(buffer, sizeof(buffer), fmt, vl);
va_end(vl);
return buffer;
}
void printArgs(int arg1, ...)
{
va_list args;
va_start(args, arg1);
int value = arg1;
while (value != -1)
{
std::cout << value << " ";
value = va_arg(args, int);
}
va_end(args);
}
int main()
{
printArgs(1, 2, 3, 4, 5, -1);
std::cout << format("rst: %s %d", "ans:", 1) << std::endl;
std::cout << format("rst: %s %d", "ans:", 2) << std::endl;
std::cout << format("rst: %s %d", "ans:", 2) << std::endl;
std::cout << format("rst: %s %d", "ans:", 3) << std::endl;
return 0;
}
- 输出:
1 2 3 4 5
rst: ans: 1
rst: ans: 2
rst: ans: 2
rst: ans: 3
3. 可变长参数宏
先看一组常见的日志输出的宏:
#define INFOD(...) iLogger::__log_func(__FILE__, __LINE__, iLogger::LogLevel::Debug, __VA_ARGS__)
#define INFOV(...) iLogger::__log_func(__FILE__, __LINE__, iLogger::LogLevel::Verbose, __VA_ARGS__)
#define INFO(...) iLogger::__log_func(__FILE__, __LINE__, iLogger::LogLevel::Info, __VA_ARGS__)
#define INFOW(...) iLogger::__log_func(__FILE__, __LINE__, iLogger::LogLevel::Warning, __VA_ARGS__)
#define INFOE(...) iLogger::__log_func(__FILE__, __LINE__, iLogger::LogLevel::Error, __VA_ARGS__)
#define INFOF(...) iLogger::__log_func(__FILE__, __LINE__, iLogger::LogLevel::Fatal, __VA_ARGS__)
调用方式:
INFOD("this is a log : %d %d %d", 1,2,3);
- 此处的 __VA_ARGS __ 为可变参数的内容,可以传递到可变长函数中。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。