想到把JNI下的
__android_log_print();函数进行封装,可是这个函数的参数是可变长参数;对于可以变长的参数,我们可以使用以下函数msdn提供的变量和函数进行实现封装可变参数传递的函数;
type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );
void va_start( va_list arg_ptr ); (UNIX version)
void va_start( va_list arg_ptr, prev_param ); (ANSI version)
参数含义:
type:参数类型
arg_ptr:指向参数列表的指针
prev_param:第一个参数的类型
type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );
void va_start( va_list arg_ptr ); (UNIX version)
void va_start( va_list arg_ptr, prev_param ); (ANSI version)
参数含义:
type:参数类型
arg_ptr:指向参数列表的指针
prev_param:第一个参数的类型
msdn也提供了相关的例程,但是在JNI使用中遇到的这个问题,就直接使用JNI的例子进行测试;
/jni/Log.h
#include <android/log.h>
#include <stdarg.h>
void Log_i(const char* log, ...);
/jni/Log.cpp
#include"Log.h"
void Log_i(const char* log, ...) {
va_list arg;
va_start(arg, log);
__android_log_vprint(ANDROID_LOG_INFO, "JniLogTools", log, arg);
va_end(arg);
}
// 测试:
#include<errno.h>
Log_i("打开文件错误 ! err = %d\n",errno);
\android-ndk-r9d\platforms\android-19\arch-arm\usr\include\android\log.h
//在这个头文件中可以看到:
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
/*
* Send a formatted string to the log, used like printf(fmt,...)
*/
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 3, 4)))
#endif
;
/*
* A variant of __android_log_print() that takes a va_list to list
* additional parameters.
*/
int __android_log_vprint(int prio, const char *tag,const char *fmt, va_list ap);
所以如果封装了可变参数,
不能使用__android_log_print();
需要使用为可变参数专门提供的函数 __android_log_vprint();