반응형

라즈비안 : 배경 바꾸기

머리말

GUI 환경 환경에서는 바탕화면에서 우클릭을 한뒤에 설정을 하면 된다. 아주 쉽다. 하지만, 다수의 라즈비안에서 배경화면을 바꾸기 위해서는 일일히 키보드와 마우스를 갈아끼면서 바꾸는 건 상당히 많은 작업을 요한다. 때문에 GUI환경이지만, CUI에서 배경을 바꾸는 방법을 기록한다.


설정파일 위치

라즈비안도 운영체제이므로 한 운영체제에 여러 계정이 있을 수 있다는 것이 이제는 보편화 되어 있다. 그리고 바탕화면은 계정별로 독립적으로 지정할 수 있다는 것을 생각하면, 계정 폴더 안에 설정파일이 있을 것이라는 것이 추측이 된다.


공식 포럼에서 알려주는 위치는 다음과 같다.

~/.config/pcmanfm/LXDE/


하지만 실제로는 위의 결로에 폴더가 없고, 마지막 하위 폴더명이 달랐었다. 이는 버전에 따라서 조금씩 차이가 있는 것으로 생각된다. 실제 경로는 다음과 같다.

~/.config/pcmanfm/LXDE-pi/desktop-items-0.conf


파일명 역시 조금씩 차이는 있을 있다. 다만, 설정파일 항목중에서 

wallpaper=/usr/share/pixel-wallpaper/road.jpg


로 되어 있는 항목이 보이면 원하는 이미지 경로와 파일명을 수정하면 된다.

수정한뒤 리부트를 하면 적용이 된다.


하지만, 배경화면을 바꾸는데 리부트 하는 건 좀 아니다 싶다. 추후에 리부트 안하고 적용하는 방법이 있다면, 알려주시면 감사하다.


참조자료

라즈베라피이스택오버플로워(?)




반응형
반응형

라즈베리 파이3 : 라즈비안 : 절전모드 및 화면보호 끄기

라즈비안의 버그?

 데스크 탑(?) 모드에서는 바탕화면에서 간단하게 마우스 우클릭하여서 GUI에서 해제하는 방법이 있다. 반면, CUI의 경우는 파일을 수정해야 하는데, 스크린세이버 설정으로 보이는 옵션을 수정을 해도 여전히 시간이 지나면, 화면이 오프 되는 것을 확인할 수 있다.

 초기 포럼에서도 이슈가 되었던 내용인데, 이 글을 작성하는 시점에도 아직 해결이 안된것 같다.


일반적인 실패 방법

 급한 사람은 안읽어도 된다. 그럴듯 하나 실패하는 방법이다. /etc/kbd/config를 편집기로 열어서 3가지 항목을 수정하거나 추가를 하는 방법이다.

항목)

BLANK_TIME=0
BLANK_DPMS=off
POWERDOWN_TIME=0




결과는 미리 언급한대로 실패



직접 디바이스를 수정(?)

 /etc/lightdm/lightdm.conf 파일중에서 [xserver] 항목이 있는데 이 한줄을 수정하면 된다.

수정내용)

xserver-command=X -s 0 dpms




 대략 내용은 강제로 안꺼지게 하는 것으로 보인다. 포럼을 보면 실패한 방법과 성공한 방법이 순서대로 나온다.


참고자료

공식 포럼




반응형
반응형

C++ Socket : 고정 구조체

알게된 배경

 기존 소켓 교재들 대부분이 C로 되어 있는것을 접하다가 C++로 옮기고 나서 소켓 프로그램을 작성할때에 구조체의 크기가 C와 같이 연속적인 형태로 메모리에 저장되지 않는다는 것을 알게 되었기에 기록으로 남긴다.


C Style Struct?

 이제는 고유 키워드가 되어 버렸다. C만 기본적으로 메모리에 직접적으로 올라가는 듯 하다. 혹은 라이브러리로 혹은 이후 표준으로 확장이 되는지 앞으로 확인이 필요할 듯하다.

 이유는 메모리에 사용자가 로드하는 대로 하지 않는 이유는 성능을 향상시키기 위해서 하는 작업이기 때문이다. 성능을 중요시한다면, 후에라도 지원이 될 듯 하지만.. C의 언어 철학은 프로그래머를 믿으라는 것이 모토이기 때문에 안될 가능성도 있다.


키워드

각 컴파일별로 선언하는 방식이 다르다. GCC 컴파일러 기준으로는 언더바로 확장된 키워드를 사용한다. __attribute__((__packed__))를  struct 와 이름 사이에 넣으면 된다.

GCC 예시)

// Header.hpp
struct __attribute__((__packed__)) SHeader
{
    char name[4];
    int32_t number;
    int32_t body_sz;
};



메모리 로드

 만약 키워드가 없을 경우에는 문자열과 숫자형을 구분하여 8바이트 단위로 메모리에 로드하게 된다. 


 예제 예시로 설명하자면, 편의상 8바이트 단위를 row라고 하면, row1에 name[4]가 로드되고 row2에 number, body_sz가 로드되어서 row가 2개이므로 총 16바이트를 차지하게 된다.

 따라서 __attribute__ 를 사용해서 실제 내부 총량이 메모리에 로드되는 것과 동일하게 하면, 12바이트가 된다(소켓 프로그램에서는 이렇게 되어야 한다).


이러한 이유로 일반적인 PC간의 소켓 통신을 할경우 헤더같이 struct로 자료형을 만들 경우 가능하면 8바이트로 딱떨어지는 형태가 되는 것이 성능저하가 적을 것이라 예측이 되는 요소이다(대부분 운영체제는 현시점에서 8바이트 형태로 최적화 되어 있는 듯 하다. 물론 이는 절대적이지 않다).


(MVC++(Microsoft Visual C++)컴파일러의 경우 다른 방법이 있는 것으로 알고 있는데, 정리할 때 메모부분을 분실해서 추후에 추가하기로 기약한다.)


여담

 C++98 이후 부터 성능을 올리기 위해서 도입이 된 것같다.

 이런식으로 언더바(_) 두개를 이용한 새로운 키워드로 기능을 확장을 하고 있는 추세이기 때문에 변수 선언시 언더바 사용을 자제할 것을 권장하고 있다. C#에서는 클래스 멤버변수를 선언시 언더바를 아직 사용하는 경향이 있지만, C++에서는 언더바 사용을 안하고 반만 헝가리식으로 소문자 m을 붙이는 경향도 있다. 어찌 되었든 권장이니 꼭 따를 필요는 없고 프로젝트 규약에 주의하자.


참고자료

스택오버 플로워


반응형
반응형

C# Socket : 고정 구조체 만들기

알게된 배경

 C++로 작성된 서버 혹은 PC와 통신을 하기 위해서는 일반적으로 고정된 크기의 Head와 고정 혹은 가변의 Body로 나누어서 통신을 하는 경우가 많다. C/C++에서는 Struct를 고정된 크기로 할당하는 것이 가능한 반면 C#에서는 별도의 코딩이 필요로 하다.

 이는 기본적으로 C#에서는 배열을 new 키워드를 통해서 정의 및 초기화를 했기때문에 struct에서는 사용이 불가능하다(반면 클래스에서는 사용가능하다).


C/C++의 고정 Struct

 그냥 배열로 선언을 해주면 된다. 아래의 SHead의 크기는 대략 40바이트가 된다. C에서는 그냥 선언해주면 되지만, C++의 경우에도 컴파일에 따라서 추가 선언을 해줘야 한다. C++에 대해서 추후 링크를 추가한다.

// head.hpp
struct SHead
{
    char name[8];
    unsigned char headType;
    char hostname[31];
};



C# unsafe

지금은 폐지된 방법이다. 초기에 불편하자 급조한 티가 난다. 참조문서는 지금도 가이드라인에 있다. 폐지된 만큼 가이드 라인에 맞게 작성해도 에러로 표시된다. 폐지된 방법은 아니고 컴파일 옵션에서 안전하지 않은 코드 컴파일 설정을 바꿔서 실행할 수 있다. C 스타일의 코딩을 자주 해야 한다면, 컴파일 옵션을 풀고 작성하는 것이 코드가 더욱 간결하다. 하지만, 키워드에서 알 수 있듯이 안전하지 않다. (그리고 마소에서 쓰지 않도록 하려고 일부러 쓰기 어렵게 만들어 놓은 방법이기도 하다)


 unsafe가 위험한 이유는 GC가 unsafe로 선언된 곳은 메모리 해제를 하지 않는다.

namespace sock
{
    public struct unsafe SHead
    {
        public Byte fixed name[8];
        public Byte headType;
        public Byte fixed hostname[31];
    }
}




C# Marshal

권장하는 방법이다. 시그니처를 이용해서 배열의 크기를 정해주는 방식이다. 사용하기 위해서는 using System.Runtime.InteropServices; 를 선언하거나 전부 적어주면 된다. pack 옵션 값은 메모리 처리 방식을 할때 단위를 1바이트로 하겠다는 의미이다.

 이러한 키워드를 추가 하지 않으면, 시스템마다 차이는 있지만, 기본적으로는 8바이트를 기준으로 처리를 한다.

namespace sock
{
    [Structlayout(LayoutKind.Sequential, pack=1)]
    public struct SHead
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public Byte[] name;
        public Byte headType;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 31)]
        public Byte[] hostname;
    }
}



 여기서 C#에서 취급하는 특징을 보면 메모리에 배열처럼 연속으로 올릴 경우를 안전하지 않은 방법으로 취급하기 때문에 여러 번거로움이 있다. 이렇게 번거롭게 만든 이유는 가능하면 사용하지 말라는 의도가 있다는 것으로 보인다. 그래도 소켓 프로그램 쪽에서는 어쩔 수 없이 사용해야 하는 경우가 있다.

잡설

 따지고 보면 C#에서 제공하는 두가지 방법들 모두 해당 자료가 안전하지 않다는 것을 명시해주는 것이다. 속도 같은 효율도 떨어진다는 건 덤.. 이러한 이유로 C로 프로그램을 작성할 경우 시스템 이해도와 잘하는 사람과 못 하는 사람간의 차이가 심하다.


참조자료

가이드 라인 unsafe

가이드 라인 unsafe 모드 컴파일

MASN문서 Marshal Array

MSDN문서 LayoutKind

블로그 :고정크기 사용방법




반응형
반응형

C# WinForm : 문자 픽셀 측정

알게된 배경

 본의 아니게 C#으로 윈도우 기반으로 간단한 프로그램을 작성하다 보니 몇몇은 나중에 다시 찾기 힘들것 같아서 이러한 것들은 기록으로 남긴다.

 문자 픽셀의 길이 경우 윈도우에서 기본적으로 제공하는 Component 를 동적(코드로)으로 작성할 경우 Label 같은 경우 autoSize를 true로 켜도 최종 크기를 size나 width, height에 갱신이 되지 않았었기 때문에 찾은 방법이다.


매서드 원형

SizeF Graphics.MeasureString(String, Font, Int32)

실제로는 앞의 2개의 인자만 있어도 된다.



예제 소스

using System.Window.Form;
using System.Drawing;

class CustumLabel : Label
{
    public CustumLabel(Sting text)
    {
        Text = "Offline";
        var width = Graphics.MeasureString(Text, Font);
        Width = (int)Math.Ceiling(width);
    }
}


위의 소스코드로 당장 변화를 확인 할 수는 없지만, 나머지도 작성하면 길어지므로 일단은 생략한다.


참조자료

MSDN 문서 Graphics.measureString Method



반응형
반응형

C++11 : 연역적 선언 auto (입문)

알게된 배경

 혼자 프로젝트를 진행을 하다 보니 가능하면 최신(2017년에 2011년에 재정된 표준을 사용하는 것이 과연 최신 일까?) 표준을 사용하기 위해서 공부하면서 알게 된 것들이다. 최신 기술이 항상 좋은 건 아니지만, 새로운 기술은 항상 이전 기술을 사용하면서 축적된 경험으로 부터 개선점이 나오기 때문에 반대로 나쁘다고만 할 수 도 없고 생각든다.

 해당 내용은 effective modern c++를 많이 참조했다.


auto 키워드

 C++98 에서도 존재하던 키워드였지만, C++11에서 급진적으로 바뀐 키워드중 하나다. 즉, C++98에도 역할이 다른 키워드이니 C++11을 경계로 이전 버전에서는 호환이 안된다. 다만, 다행스러운건 이전 버전에서는 거의 사용이 안되던 키워드였기 때문에 웬만하면 큰 문제가 발생되지 않는다.


 적절한 한글 명칭으로는 '연역적 형식선언' 정도 붙일 수 있다. auto 키워드는 JS와 C#에 존재하는 var와 유사한 역할을 한다. 즉, 객체 혹은 변수를 선언할때 초기화 하는 값에 의해서 형이 정해지는 것이다.

예시)

int a1 = 10;
auto a2 = 10;    // a1 == a2

int b1;
b1 = 10;
auto b2;    // error
b2 = 10;




 초기화 하는 형이 있어야 형을 선언할 수 있기 때문에 반드시 초기화를 해야 하며, auto 키워드는 변수형 뿐만 아니라 객체로도 사용되기 때문에 STL의 iterator를 선언할 경우 상당히 많은 코드를 줄일 수 있다.

예시)

std::vector<int> arrVec = {1, 2, 3, 4, 5};
std::vector<int>::iterator it1 = arrVec.begin();
auto it2 = arrVec.begin();
// it1[1] == it2[1]




장점

 auto 를 사용함으로써 얻는 장점은 3가지로 자주 언급이 된다.

1. 코드의 길이가 줄어듬

2. 초기화 강제화로 실수가 줄어듬

3. 코드의 유지보수(리펙토링)가 쉬워짐

4. 형 선언 실수를 방지할 수 있음


사실 STL의 자료형을 많이 사용해본 입장에서는 1, 2번의 장점이 매우 크게 느껴진다.


단점

1. 대리자(proxy) 형식 때문에 형식을 잘못 연역하는 경우가 있음

2. 코드만 봤을때 직관적이지 않음(이는 IDE의 부가 기능으로 어느정도 해결 할 수 있음)


 1번의 경우 대표적인 예로 vector<bool> 형이 많이 거론된다. bool 값은 추상적으로 1비트로 표시할 수 있기 때문에 vector 템플릿은 bool 형을 받으면 비트형으로 저장을 하게 된다. 즉, vector<bool> bVec(5)를 선언하면, bVec는 1바이트의 5비트를 갖고 있는 것이다. 문제는 C++은 바이트 단위로 처리를 하기 때문에 bool형은 실제로 바이트로 되어 있는데, 이러한 자료형의 이질성을 해소하기 위해 중간에 대리자라는 형식이 존재한다.


 문제는 이렇게 중간에 껴있는 대리자를 통하여 포인터를 넘겨 받을 경우 대리자가 어떻게 구현되었는지에 따라 영향을 받게 된다. 이러한 경우 경우에 따라 연역적 형 선언에 실패하게 된다. 따라서 이러한 경우 명시적으로 선언을 해줘야 한다.


결론

 이러한 auto 키워드 사용은 권장이지 의무는 아니다. 하지만, 장점과 단점을 생각해서 사용하는 것이 더욱 즐겁고 효율적인 코딩이 될 것이다.


참조자료

Effective Modern C++

반응형
반응형

C# OpenCV : nuget을 이용한 OpenCV 개발환경 구축

알게된 배경

C#의 높은 생산성을 알고 나서 OpenCV도 사용할 수 있지 않을까 해서 알아봤는데, 공식 OpenCV에서는 아직 C# 개발환경을 지원하지 않았다. 하지만, C#에서 실행이 가능하도록 옮겨 놓았다는 사실을 알게 되었다.

 친절하게도 오픈소스 설치과정이 어려울까봐 VS의 Nuget 명령어 창을 링크를 걸어줘서 이전과 달리 환경 설정의 부담이 매우 줄게 되었다.


Nuget이란?

비주얼 스튜디오에서 사용되는 오픈소스 프로젝트의 패키지를 관리(PM : Package Management)툴 이다. 프로젝트가 열린 상태에서 실행할 수 있다. 보통 도구 쪽에 잘 찾아보면 있다.


필요한 것

VS2015, OpenCV3.2


주의 할점

 OpenCV의 윈도우 버전 패키지를 다운로드를 받을 때 설치된 폴더의 opencv\build\x64\vc14\bin 이 경로를 환경변수에 등록을 해줘야 한다. 이 때 vc14는 VS2015를 의미하고 vc13은 VS2013 이런식으로 버전을 의미하기 때문에 이를 참고해서 다운로드 받아야 한다.

 현시점에서는 vc14가 최대 지원 버전이기 때문에 VS2015에서 개발을 진행해야 햔다.


 환경변수 잡는 경로는 자신이 압축을 푼 폴더내에서 build\x64\vc14\bin 폴더가 연결되면된다. 이는 실행에 필요한 조건이다. openCvSharp라이브러리만 가지고는 OpenCV를 실행할 수 없는 것으로 보인다.


Nuget으로 openCvSharp 설정잡기

 VS2015를 실행해서 프로젝트를 생성한다. 이후 [도구] -> [Nuget 패키지 관리자] -> [패키지관리자 콘솔] 을 실행하면 하단에 Nuget 커멘드 창이 생성된다.


Install-Package OpenCvSharp3-AnyCPU -Version 3.2.0.20170419


 이후 열심히 개발환경을 셋팅을 해준다. 그리고 테스트용 코드를 사용해보자. 테스트에 사용할 이미지는 마음에 드는 걸로 사용해도 상관없다. 다만, 이미지는 프로젝트 솔루션 내의 Debug(Debug상태에서 설치했으므로)에 넣어주어야 된다.

 설치 커맨드는 정식 github에도 링크가 있고, NuGet에도 있다.

링크 : github OpenCVSharp

링크 : NuGet OpenCVSharp


테스트용 소스코드

프로젝트는 콘솔 앱으로 생성했다.


using OpenCvSharp;

namespace openCvTest01
{
    class Program
    {
        static void Main(string[] args)
        {
            Mat src = new Mat("lena.jpg", ImreadModes.GrayScale);
            Mat dst = new Mat();

            Cv2.Canny(src, dst, 50, 200);
            using (new Window("src image", src))
            using (new Window("dst image", dst))
            {
                Cv2.WaitKey();
            }
        }
    }
}


 만만한게 레나 사진이다(지금도 살아계실지??). 테스트용 소스코드는 github에 저자가 올린 소스코드를 그대로 옮긴 것이다. 정상적으로 2장의 이미지가 보이면 된다.


참고자료

본문중 Github 링크

반응형

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

C# 싱글톤 패턴 : 동적 싱글톤  (0) 2017.09.04
C# Socket : 고정 구조체 만들기  (0) 2017.07.11
C# WinForm : 문자 픽셀 측정  (0) 2017.07.06
C# : 콘솔 앱 프로젝트에서 콘솔 감추기  (0) 2017.06.22
C# : 프로퍼티(property)  (0) 2017.01.23
반응형

C# : 콘솔 앱 프로젝트에서 콘솔 감추기

알게된 배경

 프로젝트에서 윈도우 폼UI 부분은 C#이 비교적 생산성이 높다고 해서 알아보게 되었다. 특히 콘솔 앱(.NET Framework) 중에서 동적으로 UI 생성이 가능하다는 것을 알게 되었다. 아마 내 기억에는 MFC도 콘솔에서 구현은 가능하지만 정신건강상 하지 않는게 좋은걸로 알고있다. 암튼, 이를 이용해서 생성 연습을 하던중 콘솔창을 감추는 방법을 검토하면서 기록하게 되었다.

 

참조(Reference) 설정

솔루션 탐색기에서 참조에 마우스 우클릭으로 참조 추가를 선택하여 System.Windows.Forms 항목을 체크를 표시해야 된다.

 

소스코드

아직 C#이 익숙하지 않지만, Main의 마지막 2줄은 윈도우 폼을 생성하는 코드이다.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace winform
{
    class MainApp : Form
    {         
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();
        
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
        
        const int SW_HIDE = 0;
        const int SW_SHOW = 5;
        
        static void Main(string[] args)
        {
            var handl = GetConsoleWindow();
            ShowWindow(handl, SW_HIDE);
                
            MainApp form = new MainApp();
            Application.Run(form);
        }
    }
}

 

 실행을 해보면 콘솔이 생겼다가 윈도우 폼이 생성되면서 콘솔창이 사라지는 것을 확인할 수 있다. 이는 폼 클래스내부에 메인이 함수가 있어서 발생하는 듯하다. 반드시 위의 소스처럼 사용할 필요는 없고 다만, 각 코드의 위치때문에 기록을 남긴다.

 

참고자료

스택오버플로어

 

 

반응형
반응형

C++ 패턴 : 동적 싱글턴(Dynamic Singleton)

정리하게 된 배경

 은근히 자주 사용되지만, 가끔 기억이 안나서 잘 못 작성한 코드의 오류를 한참 고민을 했기 때문에 후에 있을 시간을 절약하기 위해 기록을 한다.


싱글턴 패턴

 영문으로는 Singleton이라 하기 때문에 싱글톤이라 표기 한곳도 의외로 많지만, 위키백과에서는 싱글턴으로 표기를 하기 때문에 여기서는 싱글턴으로 표기를 하였다. 싱글턴 패턴도 여러 종류가 있지만, 실용적으로 자주 사용되는 동적 싱글턴 패턴에 대해서 소스코드를 적는다.


 싱글턴 패턴은 이름에서도 알 수 있 듯이 하나만 있다는 의미를 내포하고 있다. 즉, 실질적인 객체는 오직 하나이다. 싱글턴 객체를 사용하기 위해서는 싱글턴 내부에 선언되어 있는 인스턴스객체에 접근해서 사용이 가능하다. C/C++에서는 포인터의 개념을 들어 설명을 하면 이해가 쉽지만(물론 포인터를 이해했다는 전제하에) 포인터가 없는 다른 언어에서는 종종 인스턴스 참조와 인스턴스 생성간 혼란이 있는 듯하다.

 

 논리(이론)적 구성은 단하나의 객체 혹은 인스턴스가 존재해야 하며, 추가로 선언을 못하게 해야 한다. 여기서 동적 싱글톤의 경우 프로그램 시작과 관계없이 싱글턴의 인스턴스를 받아오려는 순간 생성이 되어 생성시점이 동적인 특징이 있다.


소스코드


// Singleton.hpp
#include <iostream>

class Singleton
{
private:
    Singleton(void);
    ~Singleton(void);
    static Singleton* _instance;
public:
    static Singleton* getInstance(void);
    void print(void);
};


// Singleton.cpp
#include "Singletion.hpp"

using namespace std;

Singleton* Singleton::_instance = nullptr;

Singleton* Singleton::getInstance(void)
{
    if(nullptr == _instance)
        _instance = new Singleton;
    return _instance;
}

void Singleton::print(void)
{
    cout << "singletion!" << endl;
}


// main.cpp
#include "Singleton.hpp"

Singleton* ins = Singleton::getInstance();
ins->print();
// or
Singleton::getInstance()->print();


주의할 점

 파일을 hpp에서 getInstance()를 정의할 경우에는 상관이 없지만, cpp에서 정의를 할 경우 static 키워드가 앞에 있어서는 안된다. 만약 사용한다면 문법적인 오류로 에러 메시지를 확인하게 된다.


참고자료

경험




반응형
반응형

Linux Ubutu 16.04 LTS : 패키지 매니져로 텔레그램 설치하기

알게된 배경

 주 운영체제를 리눅스로 넘어가기 시작하면서 다양한 프로그램을 설치하고 있던 중에 영문으로 정리된 글은 보였지만, 한글로 적힌 글이 없어서 다른 사람에게도 도움이 되게 하고자 작성하였다.

 (하지만, 리눅스 유저라면 이정도는 알아서 잘 하지 않을까?)

 

설치 방법

 그냥 아래의 명령어를 터미널에 순서대로 입력하면 된다

sudo add-apt-repository ppa:atareao/
	telegram sudo apt-get update sudo apt-get install telegram

 

 이후에 수퍼(원도우)키를 눌러서 telegram을 검색을 하면 설치된것을 확인할 수 있다.

 

참고자료

https://askubuntu.com/questions/761118/install-telegram-on-ubuntu-16-04

 

install telegram on Ubuntu 16.04

After installing Telegram Desktop on Ubuntu 16.04 by these commands: sudo add-apt-repository ppa:atareao/telegram sudo apt-get update sudo apt-get install telegram I get this error: $ telegram

askubuntu.com

 

반응형

+ Recent posts