반응형

C# : this와 base

정리배경

 무래도 C++을 사용하다가 C#을 접하게 되었기 때문에 유사한 키워드가 많아서 간과 하게 되는 부분들이 많다. 특히 this의 경우 친숙한 키위드이기 때문에 처음 공부를 할 때 스킵을 했다가 간단하면서 유용한 추가 기능이 있다는 것을 나중에 알게 되었다. base는 Java의 super와 같은 개념이나 이 역시 친숙한 기능은 아니였다.


 이러한 키워드들은 자주 사용하기 때문에 잊을 리는 없지만 정리 차원에서 작성해 놓는다.



this 키워드

 정의 된 클래스 내의 맴버(member)를 가르킬때 사용이 된다. 이러한 역할은 기존의 C++의 this와 동일한 기능이다.

 덤으로 코드 스타일은 프로젝트를 진행하는 팀별로 차이가 있지만, 맴버 객체 이름을 정할때 언더바("_")을 붙이거나 소문자 엠(m)을 붙이는 경우들이 있다.


예시1

class Book
{
    decimal isbn;
    public Book(decimal isbn)
    {
        this.isbn = isbn;
    }
}




 다른 기능은 클래스 내의 생성자에서 다른 생성자를 호출할때 사용된다. 일반적으로 생성자의 스코프(Scope)안에서 다른 생성자 호출을 되지 않지만, 생성자명 정의 직후 스코프전에 this 키워드를 사용하여 동일한 클래스내의 생성자를 호출하여 입력값을 전달하는게 가능해진다.


예시2

class Book
{
    decimal isbn;
    string title;
    string author;

    public Book(decimal isbn, string title)
        : this(isbn, title, string.Empty)
    {
    }

    public Book(decimal isbn, string title, string author)
    {
        this.isbn = isbn;
        this.title = title;
        this.author = author;
    }

}




base 키워드

 Java의 super와 같은 키워드로 상속시 부모생성자에 입력값을 전달해야 할 경우 사용이 가능하다.


예시3

// 부모(parent)
class Book
{
    decimal isbn;
    public Book(decimal isbn)
    {
        this.isbn = isbn;
    }
}

// 자식(child)
class EBook : Book
{
    public EBook(decimal isbn)
        : base(isbn)
    {
    }
}




 C#의 base는 생성자 뿐만아니라 부모의 메서드를 호출 할 경우에도 사용이 가능하다. 이러한 기능은 후에 winform 등 override하여 기존 기능을 유지하면서 확장해야 할 경우에도 사용한다.

예시4

// 부모(parent)
public class Computer
{
    bool powerOn;
    public void Boot()
    {
        powerOn = true;
    }
}

// 자식(child)
public class Notebook : Computer
{
    public void ScanFinger()
    {
        base.Boot();
    }
}




참조자료

시작하세요 C#프로그래밍(서적)

반응형
반응형

CMake 익히기 : 기초문법 (1)

작성 배경

 원래는 공식 웹 페이지에 있는 튜토리얼로 학습을 생각이었는데, 비교적 불친절한 설명과 실습하기에는 부족한 부분이 많았다. 따라서 기존 대형 오픈소스 프로젝트인 OpenCV나 VTK의 CMake 스크립트를 참고하면서 공식 서적인 "Matering CMake-Platform Build System"을 참고하여 조금씩 연습을 하려고 마음을 먹었다.


 "Matering CMake-Platform Build System"서적의 경우 대부분이 레퍼런스이고, 단계적인 설명은 약250페이지 정도 된다.



CMake

 이 글은 CMake를 익히기 위한 내용이기 때문에 CMake의 빌드 메카니즘에 대해서는 과감히 스킵을 한다.


 다만, CMake로 빌드를 하기 위해서는 몇 가지 알아야할 사항이 있다. CMake 자체는 CUI 인터페이스이다. 보니 진입장벽이 존재하고 또한 프로젝트의 규모가 커질 수 록 옵션을 어떻게 잡아야하는지가 막막해진다. 이 때문에 보조 도구가 2가지가 있다. 그리고 공식적으로 대규모의 오픈소스 프로젝트를 빌드할 경우에는 CUI보다는 GUI환경에서 빌드할 것을 권장하고 있다.


CMake-GUI

 기존의 CMake의 기능을 윈도우와 같은 GUI로 사용할 수 있는 툴이다. 리눅스 뿐만 아니라 윈도우, OS X 등에서도 사용이 가능하다. 혹시나 빌드시스템에 대해서 잘 모르지만, C/C++로 만들어진 오픈 소스 프로젝트를 윈도우에서 빌드를 해야할 경우 한번쯤은 사용하게 된다.





CCMake

 CMake-GUI의 경우 OS가 GUI환경을 제공해야 사용이 가능하다는 단점이 있다. 즉, Windows나 Linux의 X-Window와 같은 환경이 먼저 있어야 한다. 하지만, CCMake는 기존의 CUI 환경에서 CMake-GUI와 비슷하게 옵션을 선택할 수 있도록 해준다. 인터페이스는 Vi(혹은 Vim)과 유사한 단축키를 사용한다.





CMake 기초 문법

 정상적으로 CMakeLists.txt가 작동되기 위해서는 서드에 cmake_minimum_required()이 선언되어 있어야 한다. 만약 안하게 될 경우 에러 메시지를 볼 수 있다.



Agruments 구분

 CMake는 CMakeLists.txt에 작성된 스크립트대로 작동이 된다(처음 파일이름 작성시 대소문자 주의). CMake는 대부분 변수와 명령어로 구성되어 있고, 명령어는 command( arg ...) 형태로 구성되어 있다.

 대부분 명령어의 첫 arg는 대부분 특수한 의미가 있다. set()의 경우 첫 arg는 최종적으로 정의되는 변수가 된다.

 명령어의 arguments를 인식하는 것은 다음 예시와 같다.

# set의 예시

# set([변수] [arguements 값])
# set arguments를 2개로 인식
set(VAL "")
set(VAL "a;b;c")
set(VAL "a b c")
set(VAL a;b;c)

# set arguments를 4개로 인식
set(VAL "a" "b" "c")
set(VAL a b c)


 과거에 작성된 문서를 보면, CMake의 명령어들이 대문자로 되어 있지만, vs code의 확장 도구를 통해 CMakeLists.txt를 작성해보면, 명령어는 소문자로 되어 있다. 또한, 변수는 대부분 대문자로 사용하는 관습이 있다(그 이유는 항상 합리적이 이유다).



스코프(Scope) 구분

 C/C++언어에서는 중괄호를 활용해서 함수나 조건문 등의 영역인 스코프를 정의 한다. CMake에서는 이러한 중괄호가 없고 해당되는 command를 호출해서 스코프를 구분한다.


# function의 경우
function(foo)
  message("Hello foo")
endfunction()

# function foo 호출
foo()


 message()의 경우 C의 puts()처럼 입력받은 string을 한줄 출력을 한다. 이러한 명령어는 디버그할때 매우 유용하다. function()은 endfunction()으로 스코프 영역을 정의 해주고, function의 첫 arg는 function의 이름이 된다.



변수

 변수는 set()을 통해서 정의가 되고 ${}를 통해서 값을 호출한다. 또한 변수에 여러개의 값을 정의하면, 배열(혹은 리스트) 형태로 정의가 된다.

 이렇게 정의된 배열은 foreach()로 순차적으로 호출할 수 있다.



연습예제

 이제, 이 페이지에서 배운 내용을 복습해보자.


cmake_minimum_required(VERSION 2.6)

# function foo 정의
function(foo)
  message(${test})
  set(test 2 PARENT_SCOPE)
  message(${test})
endfunction()

set(test 1)
# function foo 호출
foo()

# 값확인
message(${test})

# list item_to_buy
set(item_to_buy apple orange pear beer)

# foreach item_to_buy
foreach(item ${item_to_buy})
  message("Do not forget to buy one ${item}")
endforeach()


 간단하기 때문에 CMakeLists.txt가 있는 폴더에서 다음과 같은 명령어로 빌드한다.


cmake -H. -Bbuild

위의 -B 옵션을 사용할 경우 자동으로 build 폴더를 생성하여 해당 폴더에 빌드를 한다. 빌드 과정에 다음 메시지가 출력되는 것을 확인할 수 있다.





예제에서 특이한 점을 보면, 메시지 결과를 보면, function foo()가 종료되어야 test값이 달라지는 것을 확인 할 수 있다. 이렇게 간단하게 기초 문법을 확인 해봤다.



참고

Matering CMake A Cross-Platform Build System 서적(영문)



반응형

'각종 툴' 카테고리의 다른 글

[PyCharm]기본 키 맵 해제  (0) 2020.12.20
CMake 익히기 : 기초문법 (2)  (0) 2018.02.21
CMake : 공식예제 step1 해보기  (0) 2017.12.11
반응형

코드 뷰 : 문법 하이라이트(syntax highlight)

적게된 배경

 syntaxhighlighter라는 대중적인 툴을 기존에 사용하고 있었다. 그러나 비주류 언어를 종종사용하는 나에게는 지원되는 언어가 너무나 부족했다. 특히 최근에는 업데이트가 뜸하니 새로 생길 가능성은 낮은 상황이다.


 물론 자작으로 추가를 해도 괜찮으나, 현재 하는 프로젝트들이 웹쪽이 아니다 보니 추가하기에는 부담이 되었다. 때문에 다양한 언어가 지원이 되는 highlight.js를 대안책을 사용하게 되었다.\


 다만, 라이브러리 변경으로 기존 글을 수정하는데 많은 시간이 걸렸다. 일괄로 바꿀 수 있는 방법이 있다면 좋을 것 같다. 하지만, 기존에 표기가 안되던 typescript나 cmake 같은 언어도 정식으로 표기가 되어서 그만한 가치가 있다는 생각이 든다.


참고자료

syntaxhighlighter

공식(영문)

관련 블로그(티스토리에 적용방법)


highlight.js

공식

관련 블로그(티스토리 적용방법)




반응형
반응형

라즈비안 : OpenCV를 쉘 스크립트로 설치

배경

 라즈비안에 OpenCV 설치 하는 방법에 대해서는 사실 많은 블로그에서 정리가 되어 있다. 하지만, 그 과정을 따라서 하는 것도 나쁘지는 않지만, 기본적으로 쉘에서 처리가 가능한 것들은 그냥 쉘 스크립트로 만들면 되지 않을까 하는 생각에서 작성하게 되었다.


 이번글은 작성중인 OpenCV 쉘 스크립트를 저장한 정도의 글이 될 것이다. 이후 추후에 쉘 스크립트 문법에 대해서 정리를 해 놓아야 될 것 같다.



OpenCV 설치 확인 및 제거 방법

 라즈비안이 우분투 커널을 사용하므로 마찬가지로 우분투에서 사용했었을 때 실행이 잘 되었다. 다만, 미리 설치가 되어 있을 경우 제거를 해줘야 한다.


pkg-config --modversion opencv
# 제거할 경우
cd {기본opecv 소스폴더의 build 폴더}
make uninstall


제거를 위와 같이 하지 않으면, apt-get purge로 삭제를 해도 pkg-config으로 검사할때 검출이 된다. 아마도 해당 정보를 지우지 못하는 버그가 있는 것 같다.



OpenCV 설치 쉘 스크립트(contirb포함)

 버전 수준으로 따지자면, 0.1 스크립트라고 봐야 할 것이다. 즉, 아직 부족하다고 생각 든다.

 OpenCV3.2.1외에 다른 버전이 필요한 사람이라면, OPENCV_VERSION의 숫자값을 변경하면 된다. 이미 다른 OpenCV가 설치가 되어 있다면, 설치가 진행되지 않는다. 또한, 일반적인 개발 환경으로 셋팅을 한 것이 기 때문에 실제로 배포를 하려고 할 경우는 필요한것만 빌드하도록 수정해야 한다.


#!/bin/bash

# Custom values
OPENCV_VERSION="3.3.1"
OPENCV_REPO=https://github.com/opencv/opencv/archive/"$OPENCV_VERSION".zip
OPENCVCONTRIB_REPO=https://github.com/opencv/opencv_contrib/archive/"$OPENCV_VERSION".zip

# check exit opencv modules
pkg-config --modversion opencv
if [ "$?" -eq 0 ]; then
  echo "You already install opencv"
  exit 0
fi

# Update Debian
sudo apt-get update && sudo apt-get upgrade -y
if [ "$?" -eq 1 ]; then
  echo "Faile Update or Upgrade"
fi

# Install need modules
DEPPKGS=(build-essential cmake)
DEPPKGS+=(pkg-config)
DEPPKGS+=(libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev)
DEPPKGS+=(libavcodec-dev libavformat-dev libswscale-dev libxvidcore-dev libx264-dev libxine2-dev)
DEPPKGS+=(libv4l-dev v4l-utils)
DEPPKGS+=(libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev)
# Qt4
DEPPKGS+=(libqt4-dev)
DEPPKGS+=(mesa-utils libgl1-mesa-dri libqt4-opengl-dev)
# Optimature lib
DEPPKGS+=(libatlas-base-dev gfortran libeigen3-dev)
DEPPKGS+=(python2.7-dev python3-dev python-numpy python3-numpy)

echo "=== Install depend packages ==="
for DEPPKGNAME in ${DEPPKGS[@]}; do
  dpkg -l | grep "$DEPPKGNAME"
  if [ "$?" -eq 1 ]; then
    sudo apt-get install -y "$DEPPKGNAME"
  fi
done
echo "=== End install depend packages ==="

PWD=`pwd`
WORKSPACE="$PWD"/opencv
if [ ! -d "$WORKSPACE" ]; then
  mkdir "$WORKSPACE"
  cd "$WORKSPACE"
fi

OPENCVZIP="$WORKSPACE"/opencv.zip
if [ ! -f "$OPENCVZIP" ]; then
  wget -O "$OPENCVZIP" "$OPENCV_REPO" \
  && unzip -o "$OPENCVZIP" 
  if [ "$?" -eq 1 ]; then
    echo "fail download '$OPENCVZIP'"
    exit 1
  fi
else
  upzip -o "$OPENCVZIP"
  if [ "$?" -eq 1 ]; then
    echo "fail unzip '$OPENCVZIP'"
    exit 1
  fi
fi

CONTRIBZIP="$WORKSPACE"/opencv_contrib.zip
if [ ! -f "$CONTRIBZIP" ]; then
  wget -O "$CONTRIBZIP" "$OPENCVCONTRIB_REPO" \
  && unzip -o "$CONTRIBZIP"
  if [ "$?" -eq 1 ]; then
    echo "fail download opencv_contrib.zip"
    exit 1
  fi
else
  unzip -o "$CONTRIBZIP"
  if [ "$?" -eq 1 ]; then
    echo "fail unzip '$CONTRIBZIP'"
    exit 1
  fi
fi

# OPENCVDIR="$WORKSPACE"/opencv-3.4.0
OPENCVDIR="$WORKSPACE"/opencv-"$OPENCV_VERSION"
if [ -d "$OPENCVDIR" ]; then
  cd "$OPENCVDIR"
else
  echo "does not have dir '$OPENCVDIR'"
  exit 1
fi

BUILDDIR="$OPENCVDIR"/build
if [ ! -d "$BUILDDIR" ]; then
  mkdir "$BUILDDIR" && cd "$BUILDDIR"
else
  cd "$BUILDDIR"
fi


cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D WITH_TBB=OFF \
-D WITH_IPP=OFF \
-D WITH_1394=OFF \
-D BUILD_WITH_DEBUG_INFO=OFF \
-D BUILD_DOCS=OFF \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D BUILD_EXAMPLES=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D ENABLE_NEON=ON \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-"$OPENCV_VERSION"/modules \
-D WITH_V4L=ON  \
-D WITH_FFMPEG=ON \
-D WITH_XINE=ON \
-D BUILD_NEW_PYTHON_SUPPORT=ON \
../

if [ "$?" -eq 1 ]; then
  echo "fail OpenCV cmake build '$PWD'"
  exit 1
fi

time make
if [ "$?" -eq 1 ]; then
  echo "fail OpenCV make"
  exit 1
fi

# only in raspberry
sudo make install
if [ "$?" -eq 1 ]; then
  echo "fail OpenCV install"
  exit 1
fi

echo "complete OpenCV install"
exit 0




후기

 라즈베리 파이3의 경우 듀얼코어(make 옵션의 -j2)까지는 에러가 발생하지 않지만, 마지막부분에서 문제가 있는지, 싱글코어로 빌드한것과 시간차이가 거의 없었다. 코어를 3개를 올릴 경우 빌드 막바지에서 메모리가 부족해서 빌드가 중단되는 문제가 있다.


 일부 후기에서 정정한다. swap 가상 메모리의 크기를 늘리면, 모든 코어를 빌드에 투입하여 시간을 단축 시킬 수 있다. 방법은 추후에 기회가 되면 정리 하도록 하겠다.


참조 자료

블로그 OpenCV3.4 설치




반응형
반응형

C# Winform : Detect Resize (크기 변화 감지)

알게된 배경

 운영체제 별로 화면의 화소 사이즈가 다르며, 또 사용자에 따라서 편한 크기가 있다. 이 때문에 동적으로 크기를 바꿔줘야 한다. 때문에 창의 크기가 편할때 이를 감지를 하는 것은 제품을 만들기 위해서 중요한 문제일 수 있다.


 물론 이쁘고 동적인 UI를 만든다면, 가능하면, WPF를 쓰는 방법도 현명한 선택이 될 수 있다.



소스코드

 참조한 문서에 의하면, 별로 안어렵다고 한다. 기존에 크기 변화를 감지하는 메서드를 override를 하여서 추가 시킬 수 있다. 아래의 소스코드는 생성된 초기 디자인에서 코드보기를 한뒤에 작성하였다.


// Proect name = TestResize
using System;
using System.Windows.Forms;
namespace TestResize
{
    public partial class Form1 : Form
    {
        public ResizeForm()
        {
            InitializeComponent();
            mLastState = this.WindowState;
        }

        private FormWindowState mLastState;

        protected override void OnClientSizeChanged(EventArgs e)
        {
            // 폼의 크기가 바뀔때마다 인식
            if (this.WindowState != mLastState)
            {
                // 최대, 최소, 보통 등 상태가 변할때 마다 실행됨
                mLastState = this.WindowState;
                OnWindowStateChanged(e);
            }
            else
            {
                Console.WriteLine("Detect resize: {0}, {1}", Size.Width, Size.Height);
            }
            base.OnClientSizeChanged(e);
        }

        protected void OnWindowStateChanged(EventArgs e)
        {
            Console.WriteLine("Window State: {0}", WindowState);
        }
    }
}



빌드로 실행하기 전에 프로젝트 속성의 옵션 항목중에 "응용 프로그램" --> "출력형식" --> "콘솔 응용프로그램"으로 해야 콘솔창을 통해 코드가 작동이 되는지 확인할 수 있다.



참조자료

MSDN 포럼(영문)



반응형

'C#' 카테고리의 다른 글

C# .NET : SQLLocalDB (1) 개요와 오류사례  (0) 2018.03.23
C# : this와 base  (0) 2018.02.20
C# : Queue VS ConcurrentQueue  (0) 2018.02.02
C# : 닷넷에서 Broadcast UDP를 보내기(1)  (0) 2018.01.29
C# : const vs readonly  (0) 2017.10.25
반응형

C# : Queue VS ConcurrentQueue

알게된 배경

UDP통신을 수신해야 하는데, 스레드 하나로는 프로그램의 성능을 올릴 수 없으니 당연히 멀티 스레드로 처리를 해야한다. (이는 UDP 프로토콜은 오버플러워되거나 에러가 난 패킷은 가차없이 폐기 처분하기 때문에 발생되는 문제를 막기 위함이다.) 문제는 이런 스레드가 작동되는 영역들간에 데이터 공유혹은 전달 할 수 있는 자료가 필요로 하게 된다. 이를 사용할 자료구조가 Queue였다.

 물론 링크리스트로도 충분히 구현을 할 수 도 있다.


큐의 개요

 많이 비교되는 자료구조는 스택이다. 스택은 먼저들어간게 나중에 나오는 구조(FILO or LIFO)인데 반해 큐는 들어간 순서대로 나오는 실제 세게에서 줄 서 있는 것과 같다. 추상적으로 생각을 하면, 우리가 일상중 머릿속에서 작업스케줄을 짜는 것과 같다.

 위의 예시처럼 실제로도 큐는 작업 스케줄 처럼 많이 사용되기도 한다. 큐의 종류는 선 큐, 환 큐, 링크드 큐로 분류가 되는데, 선 큐의 경우 오버플러워의 위험이 크기 때문에 잘 사용되지 않는다. 닷넷 한정으로 넣는 것을 Enqueue, 빼는 것을 Dequeue로 구현이 되어 있다.


닷넷 Queue 구조

 닷넷에서 제공하는 큐(Queue)는 환 큐에 속한다. 또한 성능을 향상시키기 위해서 정적 배열을 기반으로 하고 있다.

문제점

Queue가 비어 있을 경우 Dequeue를 시도하면 예외를 발생시킨다. 그래서 일반적으로 큐를 사용할 때 Count를 검사해서 0 이상일 때 Dequeue 사용하도록 구현을 한다. 다만, 설계시 멀티스레드에 대해서 생각을 못 한 것인지 다수의 스레드의 동시 접근시 문제가 발생된다. 때문에 Enqueue와 Dequeue에 크리티컬 섹션으로 설정해야 한다(lock을 구현해야함).

 이론상 2개의 스레드중 하나는 Enqueue만하고 다른 하나는 Dequeue만 하면, 문제가 없을 것 같지만, count등 내부적으로 공유되는 값으로 인해 간헐적인 값의 오류가 발생한다. 이러한 오류는 에러를 잘 발생시키지는 않지만, 의도한것과 다른 값을 결과로 내기 때문에 위험하다.

Queue 클래스

 Queue<T>와 달리 Queue클래스가 추가로 존재하는데, 기능이 Queue<T>보다는 많지만, 동일한 문제점이 있다.


닷넷 ConcurrentQueue 구조

 닷넷 4.0 부터 지원하는 구조이다. 기존 Queue 구조의 멀티스레드로 인한 문제가 있어서 이러한 단점을 해결하기 위한 구조이다. 기존 Queue와 큰 차이점은 인스턴스화 할때 크기를 선언하지 않는다. 이때문에 링크드 큐인것으로 생각된다.

 Enqueue는 기존 Queue와 비슷하게 사용되지만, Dequeue 대신에 TryDequeue를 사용해서 자료를 반환한다. 메서드 이름에서 알 수 있듯이 Enqueue과정이 Dequeue보다 우선 순위가 높게 구현이 되어있다. 또한 Dequeue과정이 성공/실패 여부를 반환한다. 이를 통해서 Count에 접근할 필요가 없어졌다.


유니티에서 ConcurrentQueue

 유니티에서는 닷넷을 사용할 경우 2.0에 해당되기 때문에 공식적으로 ConcurrentQueue를 사용할 수 없다. lock을 활용하여 크리티컬 섹션을 잘 설정하자.


참조 자료

스택오버 플로워

MSDN Queue

MSDN ConcurrentQueue



반응형

'C#' 카테고리의 다른 글

C# : this와 base  (0) 2018.02.20
C# Winform : Detect Resize (크기 변화 감지)  (0) 2018.02.07
C# : 닷넷에서 Broadcast UDP를 보내기(1)  (0) 2018.01.29
C# : const vs readonly  (0) 2017.10.25
C# 싱글톤 패턴 상속용 클래스  (0) 2017.09.29
반응형

C# : 닷넷에서 Broadcast UDP를 보내기(1)

알게된 배경

회사에서 임베이드 분야로 소켓 프로그램을 만들어야 할 일이 있었다. 물론 디바이스 단이 아니라 클라이언트 단의 프로그램이다. 임베이드 분야는 통신을 주로 실시간으로 해야 하며, 단거리 통신을 많이 하기 때문에 TCP 통신보다는 UDP 통신을 많이 사용한다. 특히 동시에 여러대의 디바이스에 신호를 주기 가장 적합한 방식은 Broadcast UDP 방식이다.


Broadcast UDP 란?

이름대로 특정망에 연결된 기기들에게 거의 동시에 동일한 UDP신호를 정해진 포트로 보내는 방식이다. 여기서 거의 동시라는 건 라즈베리 파이같은 기기로 테스트해 본 결과 0.01초 내외의 오차가 있다. 이는 디바이스의 상태와 성능에 따라 조금씩 차이가 있는 것으로 보인다.


Broadcast UDP 원리

사실 원리라고 말하기는 애매하고 규약이라 보는 것이 나을 것이다. 규약조건은 IPv4 기준으로 망을 제공하는 네트워크의 서브 마스크에서 허용되는 IPv4 주소의 비트가 1이 되게 보내면 해당신호는 Broadcast로 인식이 된다. 따라서 Broadcast UDP를 보내기 위해서는 해당 네트워크 망의 서브넷 마스크와 네트워크 제공 IP주소 체계를 알아야 한다.


[보조 설명] 서븐넷 마스크와 Broadcast UDP

서브넷 마스크 주소체계의 고정값과 비고정값을 구분하는 기준이라고 생각하면 된다. 마스크라는 단어의 의미 자체가 가면 혹은 가린다는 뜻이다. 네트워크의 신호는 주로 비트로 표현이 되는데, 마스크의 비트가 1일 경우 해당 값은 가려지는 것이고, 반대로 0 이 되는 부분은 가려지지 않은 값이다.

즉, 255.255.255.0 이라고 할경우 255는 비트상 모두 1이 되어서 255가 되는 부분은 가려져서 내부망 주소에서 구분을 하지 않는다. 반면 0인 부분은 8비트를 가리지 않아서 이론상 0~255의 주소를 구분할 수 있다.

다만, 서브마스크로 가려지지 않은 모든 비트값이 1이 될 경우에는 받는 UDP신호는 Broadcast UDP로 인식이 되어서 특정 IP가 아닌 모든 디바이스에 동일하게 전송하도록 약속이 되어 있다.



소스코드

Broadcast UDP의 규약과 구글 검색을 통한 MSDN 문서를 좀 더 찾아보면 간단히 찾아 볼 수 있다. 물론 스택오버플로어의 내용에다가 약간의 문자열을 파지 하는 방법도 있지만, 가능하면 MS에서 만들어 놓은 class를 활용을 해보도록 하자.


using System;
using System.Net.NetworkInformation;

class Program
{

// print ip address, submask
private void PrintIpAddressAndSubmask()
{
    NetworkInterface[] netInter = NetworkInterface.GetAllNetworkInterfaces();
    foreach(var itInter in netInter)
    {
        // 인터넷 혹은 망에 연결된 것만 남김
        if(itInter.OperationsalStatus != OperationalStatus.Up)
            continue;
        // 유선(Ethernet)과 무선(Wireless80211)만 남김
        if(itInter.NetworkInterfaceType != NetworkInterfaceType.Ethernet
            && itInter.NetworkInterfaceType != NetworkInterfaceType.Wireless80211)
            continue;
        var unicast = itInter.GetIpProperties().UnicastAddress;
        foreach(var itUnicast in unicast)
        {
            // Ip v6는 걸러냄
            if(itUnicast.IPv4Mask.Address == 0)
                continue;
            console.writeLine("\tIp Address : {0}", itUnicast.Address);
            console.writeLine("\tSubnet Mask : {0}", itUnicast.IPv4mask);
        }
    }
}

}





참조 자료

MSDN : UDP 서비스 사용 문서
MSDN : NetworkInterface 클래스



반응형

'C#' 카테고리의 다른 글

C# Winform : Detect Resize (크기 변화 감지)  (0) 2018.02.07
C# : Queue VS ConcurrentQueue  (0) 2018.02.02
C# : const vs readonly  (0) 2017.10.25
C# 싱글톤 패턴 상속용 클래스  (0) 2017.09.29
C# 싱글톤 패턴 : 동적 싱글톤  (0) 2017.09.04
반응형

Octave : 이미지 출력과 필터 연산

간단한 소개

 다양한 분야에서 연구를 수행할 때 사용되는 대표적인 도구로 Matlab이 사용되고 있다. 초기에는 그저 수학용 툴이었지만, 어느센가 확장을 거듭하여 신호처리, 영상처리, 시뮬레이션 등 다양한 분야에서 사용되게 되었다.

 문제는 이러한 다양하게 활용이 가능한 툴인 만큼 고가의 제품이다. 덕분에 대학이나 대기업이 아닌 이사아 중소기업에서는 구매하기 어려운 가격이다. 대신 Matlab 만큼은 아니지만, 같은 문법과 같은 스크립트 파일을 비슷한 성능에 실행을 할 수 있는 툴이 나온 것이 Octave 이다. 흔히 GNU Matlab이라는 키워드로도 검색이 된다.


준비물

lena.jpg 과 같은 샘플 이미지 파일, octave


이미지 그라디언트

m파일로 작성하지 않고 octave의 프롬프트창(혹은 입력커멘드 창)에서 우선 이미지가 있는 폴더로 이동을 해야 한다. 쉘 처럼 cd 명령어를 통해 이미지가 있는 폴더로 이동하자.


sample = imread("lena.jpg");
pkg load image
I = rgb2gray(sample);
# double 형으로 형변환 역할
S = conv2(I, ones(5, 5)/25, "same");
[Dx, Dy] = gradient(S);
imshow(sample);
figure(2);
imshow(I);
figure(3);
imshow(Dx);
figure(4);
imshow(Dy);



결과물



openCV를 사용해봤다면, 몇몇 함수는 이름이 비슷해서 익숙할 것이다. 필터링을 한거지만, 행렬 연산을 전문으로 하는 프로그램 입장에서는 행렬연산을 하는 것이기 때문에 사실 필터링을 위한 다른 툴이 필요하지는 않는다.


여기서는 Dx, Dy를 그래도 출력했지만, 분석시에는 두 값을 이용해 기울기값을 사용한다. 이에 대한 자세한 내용은 "디지털 영상처리"같은 서적을 참조할 것


참고자료

octave 위키 문서

GNU octave 이미지 프로세싱 참조자료



반응형
반응형

C++ 컴파일 에러 : cannot bind ~

에러 메시지

cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'


발생하는 사례

 보통 cout 표준 클래스에서 자주 발견된다. 뿐만 아니라 연산자 오버라이딩이 된 클래스를 사용하다 보면 종종 발생된다.


에시1

// c++11 more than
#include <iostream>

using namespace std;

enum class COLOR
{RED, GREEN, BLUE};

int main(const int argc, const char * argv[])
{
    cout << "Color enum Red : "
        << static_cast<int>(COLOR::RED) << endl;    // No Error
    cout << "Color enum Green : " << COLOR::GREEN << endl;    // Error!
    return 0;
}




예시2

 이 예시는 보기 조금 민망하다..

// c++11 more than
#include <iostream>
#include <vector>

using namespace std;

int main(const int argc, const char * argv[])
{
    cout << "vectors : " << vector<int>{1, 2, 3} << endl;    // Error!
    return 0;
}




원인

 입출력 관련 클래스가 연산자 오버라이딩이 가능해지면서 직관적으로 코드를 작성할 수 있게 되었는데, 그러다 보니 정의 되지 않은 타입을 연산자로 받을 경우 발생되는 간단한 에러이다. 별거 아닌 에러이지만, 사람이 종종 실수를 할 수 있기 때문에 볼 수 있다. 다만, 메시지의 의미를 파악하는 연습을 하도록 하자.

 해결 방법은 연산자가 이해할 수 있는 타입으로 캐스팅을 해주거나 연산자 오버라이드를 추가 해주면 된다. 이 글을 작성하는 시점에서는 이런 실수를 방지 하기 위해 연산자 오버라이딩은 가능하면 자제하는 추세인걸로 알고 있다.


참고자료

스택오버플러워 질문



반응형

'C++' 카테고리의 다른 글

C++11 : 범위기반 for 문  (0) 2018.03.04
C++11 : STL std::array 정적배열  (0) 2018.03.04
C++ Socket : 고정 구조체  (0) 2017.08.04
C++11 : 연역적 선언 auto (입문)  (0) 2017.07.03
C++ 패턴 : 동적 싱글턴(Dynamic Singleton)  (0) 2017.06.16
반응형

라즈베리 파이 한글문서(링크)

 기존 라즈베리 파이의 공식 문서(영문)을 비공식적으로 번역을 해놓은 페이지 이다. 영어 문서를 봐도 상관이 없겠지만, 아무래도 읽는 속도에서 차이가 나기 때문에 가능하면 한글 문서를 보는 것이 유리할 듯하여 기록을 남긴다.


유용했던 분은 이런 일 하는 분들의 문서에 추천을 눌러주자(여기글 말고 링크한 글)


링크

라즈베리 파이 문서(한글)




반응형

+ Recent posts