C++용 Log 클래스

|

C++ 에서 사용할 수 있는 Log 클래스입니다. 안드로이드 NDK 환경이나 Windows 환경 등에서도 사용할 수 있습니다. 사용법을 최대한 안드로이드 Java의 Log 클래스와 비슷하게 흉내냈습니다.


Log.h

#ifndef SNOWDEER_LOG_H
#define SNOWDEER_LOG_H

class Log {
 public:
  static void v(const char* format, ...);
  static void d(const char* format, ...);
  static void i(const char* format, ...);
  static void w(const char* format, ...);
  static void e(const char* format, ...);

 private:
  Log() {}
  virtual ~Log() {}
};

#endif //SNOWDEER_LOG_H


Log.cc

#include "Log.h"

#include <cstdio>
#ifdef __ANDROID__
#include <android/log.h>
#else
#include <stdarg.h>
#endif

const char* gLogTag = "SDLog";

#ifdef __ANDROID__
#define PLOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, gProseLogTag, __VA_ARGS__)
#define PLOGD(...) __android_log_print(ANDROID_LOG_DEBUG, gProseLogTag, __VA_ARGS__)
#define PLOGI(...) __android_log_print(ANDROID_LOG_INFO, gProseLogTag,__VA_ARGS__)
#define PLOGW(...) __android_log_print(ANDROID_LOG_WARN, gProseLogTag,__VA_ARGS__)
#define PLOGE(...) __android_log_print(ANDROID_LOG_ERROR, gProseLogTag, __VA_ARGS__)
#define PLOGF(...) __android_log_print(ANDROID_FATAL_ERROR, gProseLogTag,__VA_ARGS__)
#define PLOGS(...) __android_log_print(ANDROID_SILENT_ERROR, gProseLogTag,__VA_ARGS__)
#else
#define LOGV(...)
#define LOGD(...)
#define LOGI(...)
#define LOGW(...)
#define LOGE(...)
#define LOGF(...)
#define LOGS(...)
#endif

void Log::v(const char* format, ...) {
  char message[1024] = { 0, };

  va_list lpStart;
  va_start(lpStart, format);
  vsprintf(message, format, lpStart);
  va_end(lpStart);

  printf("[%s] %s\n", gLogTag, message);
  LOGV("%s", message);
}

void Log::d(const char* format, ...) {
  char message[1024] = { 0, };

  va_list lpStart;
  va_start(lpStart, format);
  vsprintf(message, format, lpStart);
  va_end(lpStart);

  printf("[%s] %s\n", gLogTag, message);
  LOGD("%s", message);
}

void Log::i(const char* format, ...) {
  char message[1024] = { 0, };

  va_list lpStart;
  va_start(lpStart, format);
  vsprintf(message, format, lpStart);
  va_end(lpStart);

  printf("[%s] %s\n", gLogTag, message);
  LOGI("%s", message);
}

void Log::w(const char* format, ...) {
  char message[1024] = { 0, };

  va_list lpStart;
  va_start(lpStart, format);
  vsprintf(message, format, lpStart);
  va_end(lpStart);

  printf("[%s] %s\n", gLogTag, message);
  LOGW("%s", message);
}

void Log::e(const char* format, ...) {
  char message[1024] = { 0, };

  va_list lpStart;
  va_start(lpStart, format);
  vsprintf(message, format, lpStart);
  va_end(lpStart);

  printf("[%s] %s\n", gLogTag, message);
  LOGE("%s", message);
}

사용자 계정 관리하기

|

계정 생성

리눅스에서 사용자 계정은 다음 명령어를 이용해서 생성할 수 있습니다. 기본적으로 -m 옵션을 붙여서 사용자의 홈 디렉토리(Home Directory)를 생성할 수 있습니다.

sudo useradd -m [사용자 ID]

ex) sudo useradd -m snowdeer

계정을 생성한 다음에는 ls /home 명령어를 이용해서 확인할 수 있습니다.


패스워드 설정

패스워드는 passwd 명령어를 이용해서 설정할 수 있습니다.

sudo passwd snowdeer

ex)
pi@snowdeer_raspberry:~ $ sudo passwd snowdeer
Enter new UNIX password: ********
Retype new UNIX password: ********
passwd: password updated successfully


패스워드 변경

현재 로그인해 있는 계정의 패스워드를 변경할 경우는 다음과 같이 passwd 명령어만 입력하면 됩니다.

sudo passwd


계정 삭제

계정 삭제는 userdel 명령어로 가능합니다.

sudo userdel snowdeer

계정을 삭제해도 /home 밑에 홈 디렉토리는 남아 있기 때문에 수작업으로 삭제를 해주시면 됩니다.

Eclipse에서 C++11 이상 지원하도록 설정하는 방법

|

C++11

C언어는 지금도 계속해서 발전하고 있습니다. 2011년 C++11 규격이 정해졌으며, 그 이후에도 계속하여 발전하고 있습니다. 지금은 현재 C++14, C++17 까지 나온 상태입니다. 개인적인 생각으로는 C++11에서 아주 큰 변화(스마트 포인터 지원 및 Thread 표준화)가 있었던 것 같습니다. 그래서 신규 프로젝트를 진행한다면 적어도 C++11 이상은 사용하는 것이 좋다고 생각합니다. 그 중에서도 스마트 포인터(Smart Pointer)는 메모리 릭(Memory Leak) 방지에 아주 큰 도움이 되며, 표준화가 된 쓰레드(Thread)는 멀티 플랫폼 지원에 유리할 것 같습니다.


Eclipse for C++11

Visual Studio나 CLion 등 좋은 C++ IDE가 많이 있지만, 회사에서는 아무래도 Eclipse를 많이 사용하게 되네요. 아마도 라이센스를 크게 신경쓸 필요가 없어서이지 않을까 싶습니다. 그래서 Eclipse에서 C++11 이상을 지원하는 방법을 포스팅해봅니다. 저는 현재 PC에 MinGW를 설치했기 때문에 포스팅을 MinGW 기준으로 설명을 하고 있지만, MinGW가 아니더라도 Cygwin 등 기타 다른 컴파일러에서도 거의 동일한 설정을 하면 됩니다.


image

일단 새로운 프로젝트를 시작하고 컴파일러를 MinGW를 선택합니다. (굳이 새로운 프로젝트를 시작할 필요없이 세팅에서 바로 설정을 할 수도 있지만, 여기서는 실제로 C++11 문법으로 잘 빌드가 되는지 확인하기 위해서 새로운 프로젝트를 만들어서 테스트를 합니다.)


image -fullwidth

Project > Properties > C/C++ Build / Settings > Tool Settings에서 [GCC C++ Compiler] 항목과 [GCC C Compiler] 항목에서 [Miscellaneous] 항목을 찾습니다. 그리고 [Other flags] 뒷 부분에 다음 옵션을 추가합니다.

-std=c++0x


이제 간단한 코드를 작성하여 테스트를 해봅니다. 코드 예제는 다음과 같습니다. 코드 작성 후 빌드를 실행해봅니다.


#include <cstdio>
#include <memory>
#include <string>
#include <thread>

using namespace std;

int main(void) {
  printf("Hello SnowDeer.\n");

  shared_ptr<string> a = make_shared<string>();

  return 0;
}


image -fullwidth


위 이미지와 같이 빌드가 잘 되는 것을 확인할 수 있습니다.

하지만 다음 이미지에 나온 것처럼 문제점이 하나 있습니다.


image -fullwidth

컴파일 및 빌드는 잘되지만, Eclipse의 에디터에서는 오류가 난 것처럼 표시되고 있습니다. 그냥 무시하고 개발을 진행해도 되지만, 시각적으로 상당히 불편합니다. 이럴거면 IDE를 사용하는 의미가 없을 것 같네요. 이를 해결하기 위해서는 IDE 내의 에디터키가 C++11 이상을 지원하도록 추가 설정을 해주어야 합니다. 앞서 설정한 내용은 컴파일러의 옵션만 설정한 것이기 때문에 추가 설정이 필요합니다.


image -fullwidth

Project > Properties > C/C++ General > Preprocessor Include Paths, Macros etc에서 [Providers] 탭을 선택한 다음 [CDT GCC Built-in Compiler Settings MinGW] 항목을 선택합니다. 그리고 아래쪽에 있는 Flag 설정 칸에 다음 옵션을 추가해줍니다.

-std=c++0x


image

그 이후 C/C++ Index Rebuild 를 수행해주면 Eclipse IDE가 C++11 문법을 정상적으로 인식하기 시작합니다.


image -fullwidth

이제 깔끔하게 Eclipse에서 C++11 이상의 문법들로 프로그램을 작성할 수 있습니다.

블루투스 페어링하기

|

라즈베리 파이(Raspberry PI)와 블루투스 기기간의 페어링하는 방법입니다. 터미널 명령어를 이용한 블루투스 페이렁 방법을 소개합니다.

먼저 라즈베리 파이 터미널에서 다음 명령어를 입력합니다.

bluetoothctl

image -fullwidth

위 스크린샷과 같이 프롬프트가 ‘[bluetooth]’로 바뀌면, 이제 블루투스 명령어들을 사용할 수 있습니다.

이 상태에서 사용할 수 있는 블루투스 명령어들은 다음과 같습니다. (명령어 ‘help’를 통해 확인할 수 있습니다.)

image -fullwidth


라즈베리 파이의 블루투스 정보는 다음 명령어를 이용해 조회할 수 있습니다.

show

image -fullwidth


다른 디바이스들을 탐색하기 위해서 디스커버리(Discovery)를 수행하거나 종료하는 명령어는 다음과 같습니다. 이 때, 페어링하고 싶은 디바이스(ex. 스마트폰)에서도 블루투스 검색 허용을 활성화해줘야 아래 명령어로 검색을 할 수 있습니다. 탐색이 되지 않은 상태에서 Bluetooth MAC Address를 이용한 페어링을 시도했을 때는 페어링이 되지 않더군요.

scan on
scan off

image -fullwidth


자기 자신을 다른 디바이스에서 보이도록 하는 명령어는 다음과 같습니다.

discoverable on
discoverable off


페어링을 원하는 디바이스의 맥 어드레스(MAC Address)를 기억해둡니다. 그리고 페어링을 시도합니다.

pair [MAC Address]


페어링이 되면 스마트폰에 페어링 확인 창이 뜹니다. 스마트폰 화면에서 확인을 눌러줍니다. 그 다음 trust 명령어를 수행합니다.

trust [MAC Address]

image -fullwidth


이제 페어링이 끝났습니다. 다음 명령어를 통해 현재 페어링된 디바이스 목록을 조회할 수 있습니다.

paired-devices

Windows 10 - 복구 파티션 삭제하기

|

복구 파티션 삭제하기

집에 있는 데스크탑을 업그레이드하고, 예전에 사용하던 하드 디스크를 연결했습니다. 덕분에 현재 컴퓨터에 하드 디스크 3개가 주렁주렁 매달려 있습니다. 세세하게 나눴던 파티션을 좀 정리하고 커다란 공간을 쓰고 싶어서 각 하드 디스크의 파티션 정리를 하려고 했습니다.

image


하지만, 삭제가 안되는 파티션이 있네요 !!! ‘복구 파티션’이라고 표시된 영역은 컴퓨터 관리 윈도우에서 건드릴 수가 없게 되어 있었습니다. 그냥 무시하고 나머지 영역만 쓸까 생각도 했지만, 17.08 GB는 너무 큰 용량이라서 완전히 삭제하는 방법을 찾아보게 되었습니다.

관리자 모드로 커맨드 창 실행

먼저 관리자 모드로 커맨드 창을 실행합니다.

image

그리고 커맨드 창에서 다음 명령어를 실행합니다.

image

그 이후, 아까 삭제를 할 수 없었던 물리 디스크를 선택하고(저는 디스크 3번이 삭제가 안되었기 때문에 3번 디스크를 선택했습니다.)

select disk [번호]

파티션 리스트를 확인합니다.

list partition

image

그 이후 지우고자 하는 파티션을 선택하고

select partition [번호]

삭제를 합니다.

delete partition override

image

그런 다음 컴퓨터 관리 윈도우로 간 다음 파티션이 정상적으로 삭제된 것을 확인할 수 있습니다.

image