androidローカルC++言語実行可能プログラムを最初から構築
9658 ワード
本文はcsdn lidpから有名な出典を転載した.
前編ではAndroid mkファイルの作成について説明しましたが、本編では具体的な例を挙げます.このプログラムの機能はandroidが提供するlog機能をカプセル化し、統一的なインタフェース関数を提供します.
droid_log(LOG_DEBUG,,,,,);
ロゴの印刷レベルは、スイッチによって決定することができます(ロゴr.hのLOGLEVELマクロを変更します).
LOG_VERBOSE, LOG_DEBUG,LOG_NOTICE,LOG_WARNING, LOG_ERROR.
logcatでは、印刷レベル、タイムスタンプ、関数名、ファイル名、および異なるレベルの構文に基づいてハイライト表示されます.
使用例:
droid_log(LOG_DEBUG, "test debug");
最初のパラメータは、printfと同様に、上記の5つのレベルであり、後に可変パラメータのリストである.
この機能はandroidでコンパイルし、ソースパッケージをexternal/の下に置くとmmでコンパイルできます.
ディレクトリ構造:
/android/external/hello
├── Android.mk
├── CleanSpec.mk
├── include
│ └── logger.h
└── src
├── Android.mk
├── hello.cpp
└── logger.cpp
ソース:
logger.h
logger.cpp
ファイルcpp :
# src/Android.mk
============
ファイルmk
helloディレクトリの下でmm生成実行可能プログラムhello(out/targate/product/system/binディレクトリ)を実行し、ボードにコピーし、./helloを実行
logcatでは印刷が表示されます.
転載お断り.
前編ではAndroid mkファイルの作成について説明しましたが、本編では具体的な例を挙げます.このプログラムの機能はandroidが提供するlog機能をカプセル化し、統一的なインタフェース関数を提供します.
droid_log(LOG_DEBUG,,,,,);
ロゴの印刷レベルは、スイッチによって決定することができます(ロゴr.hのLOGLEVELマクロを変更します).
LOG_VERBOSE, LOG_DEBUG,LOG_NOTICE,LOG_WARNING, LOG_ERROR.
logcatでは、印刷レベル、タイムスタンプ、関数名、ファイル名、および異なるレベルの構文に基づいてハイライト表示されます.
使用例:
droid_log(LOG_DEBUG, "test debug");
最初のパラメータは、printfと同様に、上記の5つのレベルであり、後に可変パラメータのリストである.
この機能はandroidでコンパイルし、ソースパッケージをexternal/の下に置くとmmでコンパイルできます.
ディレクトリ構造:
/android/external/hello
├── Android.mk
├── CleanSpec.mk
├── include
│ └── logger.h
└── src
├── Android.mk
├── hello.cpp
└── logger.cpp
ソース:
logger.h
/*! \file
*
* \brief Logging routines,Support for logging to console.
*
* \author openser <[email protected]>
*
* \extref android/log.h
*
*
* - this is a wraper for android log, user may see log in logcat.
* - utility-related API functions, used by internal.
* -
*
* \ref none
*/
#ifndef _LOGGER_H_
#define _LOGGER_H_
#include <android/log.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define LOGLEVEL 5
#define ESC 0x1b
#define ATTR_RESET 0
#define ATTR_BRIGHT 1
#define ATTR_DIM 2
#define ATTR_UNDER 4
#define ATTR_BLINK 5
#define ATTR_REVER 7
#define ATTR_HIDDEN 8
/* termanal color define */
#define COLOR_BLACK 30
#define COLOR_GRAY (30 | 128)
#define COLOR_RED 31
#define COLOR_BRRED (31 | 128)
#define COLOR_GREEN 32
#define COLOR_BRGREEN (32 | 128)
#define COLOR_BROWN 33
#define COLOR_YELLOW (33 | 128)
#define COLOR_BLUE 34
#define COLOR_BRBLUE (34 | 128)
#define COLOR_MAGENTA 35
#define COLOR_BRMAGENTA (35 | 128)
#define COLOR_CYAN 36
#define COLOR_BRCYAN (36 | 128)
#define COLOR_WHITE 37
#define COLOR_BRWHITE (37 | 128)
/* log level define */
#define _LOG_ __FILE__, __LINE__ ,__PRETTY_FUNCTION__
#ifdef LOG_VERBOSE
#undef LOG_VERBOSE
#endif
#ifdef LOG_VERBOSE
#undef LOG_VERBOSE
#endif
#define LOG_VERBOSE 0
#define LOGGER_VERBOSE LOG_VERBOSE, _LOG_
#ifdef LOG_DEBUG
#undef LOG_DEBUG
#endif
#ifdef LOG_DEBUG
#undef LOG_DEBUG
#endif
#define LOG_DEBUG 1
#define LOGGER_DEBUG LOG_DEBUG, _LOG_
#ifdef LOG_NOTICE
#undef LOG_NOTICE
#endif
#define LOG_NOTICE 2
#define LOGGER_NOTICE LOG_NOTICE, _LOG_
#ifdef LOG_WARNING
#undef LOG_WARNING
#endif
#ifdef LOG_WARNING
#undef LOG_WARNING
#endif
#define LOG_WARNING 3
#define LOGGER_WARNING LOG_WARNING, _LOG_
#ifdef LOG_ERROR
#undef LOG_ERROR
#endif
#ifdef LOG_ERROR
#undef LOG_ERROR
#endif
#define LOG_ERROR 4
#define LOGGER_ERROR LOG_ERROR, _LOG_
extern const char *loglevels[];
extern int colors[];
extern char dateformat[256];
/* out put time in a format */
void print_time();
/* fileter special sequeces ,such as ESC */
void term_filter_escapes(char *line);
/* copy string , This is similar to strncpy, with two important differences:
- the destination buffer will always be null-terminated
- the destination buffer is not filled with zeros past the copied string length
*/
void tsk_copy_string(char *dst, const char *src, size_t size);
/* format the input sring to specific color */
char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout);
/* out put log to console in diff level
the level is : LOG_DEBUG, LOG_NOTICE, LOG_VERBOSE, LOG_ERROR, LOG_WARNING
an out put example :[Jan 2 04:55:55] DEBUG[1604]: src/transactions/tsip_transac_layer.c:282 tsip_transac_layer
*/
void _droid_log(int level, const char *file, int line, const char *function, const char *fmt, ...);
/*put a sring to console*/
void tsk_console_puts(char *str);
/*!
* \brief Log a DEBUG message
* \param level The minimum value of LOGLEVEL for this message
* to get logcat
*/
#define droid_log(level, ...) do { \
if (level <= (LOGLEVEL) ) { \
if(level == 0) \
_droid_log(LOGGER_VERBOSE, __VA_ARGS__); \
else if( level == 1) \
_droid_log(LOGGER_DEBUG, __VA_ARGS__); \
else if(level == 2) \
_droid_log(LOGGER_NOTICE, __VA_ARGS__); \
else if(level == 3) \
_droid_log(LOGGER_WARNING, __VA_ARGS__); \
else if(level == 4) \
_droid_log(LOGGER_ERROR, __VA_ARGS__); \
else \
_droid_log(LOGGER_DEBUG, __VA_ARGS__); \
} \
} while (0)
#endif
logger.cpp
/*! \file
*
* \brief Logging routines,Support for logging to console.
*
* \author openser <[email protected]>
*
* \extref android/log.h
*
*
* - this is a wraper for android log, user may see log in logcat.
* - utility-related API functions, used by internal ccdt.
* -
*
* \ref none
*/
#include "logger.h"
#include <android/log.h>
/* log level definition */
const char *loglevels[] = {
"VERBOSE",
"DEBUG",
"NOTICE",
"WARNING",
"ERROR",
};
/* used by term_color */
int colors[] = {
COLOR_GREEN,
COLOR_BRGREEN,
COLOR_YELLOW,
COLOR_BRRED,
COLOR_RED,
COLOR_BRBLUE,
COLOR_BRGREEN,
};
/* date format , example : Jan 2 04:55:55*/
char dateformat[256] = "%b %e %T";
void print_time()
{
struct timeval tv;
struct tm* ptm;
char time_str[128];
long milliseconds;
gettimeofday(&tv, NULL);
ptm = localtime(&tv.tv_sec);
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", ptm);
milliseconds = tv.tv_sec/1000;
printf("%s.%03ld
", time_str, milliseconds);
}
void tsk_copy_string(char *dst, const char *src, size_t size)
{
while(*src && size) {
*dst++ = *src++;
size--;
}
if(__builtin_expect(!size, 0))
dst--;
*dst = '\0';
}
void tsk_console_puts(char *str)
{
fprintf(stderr,"%s", str);
fflush(stderr);
}
void term_filter_escapes(char *line)
{
int i;
int len = strlen(line);
for (i = 0; i < len; i++) {
if (line[i] != ESC)
continue;
if ((i < (len - 2)) &&
(line[i + 1] == 0x5B)) {
switch (line[i + 2]) {
case 0x30:
case 0x31:
case 0x33:
continue;
}
}
/* replace ESC with a space */
line[i] = ' ';
}
}
char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
{
int attr=0;
char tmp[40];
memset(outbuf, 0, maxout);
if (!fgcolor && !bgcolor) {
tsk_copy_string(outbuf, inbuf, maxout);
return outbuf;
}
if ((fgcolor & 128) && (bgcolor & 128)) {
/* Can't both be highlighted */
tsk_copy_string(outbuf, inbuf, maxout);
return outbuf;
}
if (!bgcolor)
bgcolor =COLOR_BLACK;
if (bgcolor) {
bgcolor &= ~128;
bgcolor += 10;
}
if (fgcolor & 128) {
attr = ATTR_BRIGHT;
fgcolor &= ~128;
}
if (fgcolor && bgcolor) {
snprintf(tmp, sizeof(tmp), "%d;%d", fgcolor, bgcolor);
} else if (bgcolor) {
snprintf(tmp, sizeof(tmp), "%d", bgcolor);
} else if (fgcolor) {
snprintf(tmp, sizeof(tmp), "%d", fgcolor);
}
if (attr) {
snprintf(outbuf, maxout, "%c[%d;%sm%s%c[0;%d;%dm", ESC, attr, tmp, inbuf, ESC,
COLOR_WHITE, COLOR_BLACK + 10);
} else {
snprintf(outbuf, maxout, "%c[%sm%s%c[0;%d;%dm", ESC, tmp, inbuf, ESC, COLOR_WHITE,
COLOR_BLACK + 10);
}
return outbuf;
}
void _droid_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
{
if(level > LOGLEVEL){
return;
}
time_t t;
struct tm *tm;
char date[64];
char linestr[64];
char tmp1[64];
char buf[256];
char buf1[256];
char msg[512];
int res;
va_list ap;
t = time(NULL);
tm = localtime(&t);
memset(date, 0, sizeof(date));
memset(buf, 0, sizeof(buf));
memset(buf1, 0, sizeof(buf1));
memset(msg, 0, sizeof(msg));
strftime(date, sizeof(date), dateformat, tm);
snprintf(linestr,sizeof(linestr),"%d", line);
snprintf(buf,sizeof(buf),"[%s] %s[%ld]: %s %s: ",date,term_color(tmp1, loglevels[level], colors[level], 0, sizeof(tmp1)),(long)getpid(),
linestr, function);
term_filter_escapes(buf);
va_start(ap, fmt);
res = vsnprintf(buf1,sizeof(buf1) - 1,fmt, ap);
va_end(ap);
snprintf(msg, sizeof(msg) -1, "%s%s",buf,buf1);
__android_log_print(ANDROID_LOG_DEBUG, "%s",msg);
}
ファイルcpp :
#include "logger.h"
int main(int argc, char **argv)
{
droid_log(LOG_DEBUG, "test debug
");
return 0;
}
# src/Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
hello.cpp logger.cpp
LOCAL_MODULE_TAGS:= optional
LOCAL_C_INCLUDES := external/hello/include
LOCAL_MODULE:= hello
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libutils
include $(BUILD_EXECUTABLE)
============
ファイルmk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
include $(call all-makefiles-under,$(LOCAL_PATH))
helloディレクトリの下でmm生成実行可能プログラムhello(out/targate/product/system/binディレクトリ)を実行し、ボードにコピーし、./helloを実行
logcatでは印刷が表示されます.
転載お断り.