BPR (Business Process Re-engineering) ; 업무 재설계

BPR[비피알]은 1990년대 초 미국에서 제창한 개념으로서, 사업활동을 영위하는 조직의 측면에 있어, 작업을 개선하고 자원의 사용을 보다 효율적으로 만들기 위하여, 하나의 목적으로 처음부터 다시 근본적인 변화를 만드는 것을 의미한다. BPR은 업무 프로세스의 근본적인 재고(再考)가 수반되며, 원가, 서비스품질, 직원들의 활력 등과 같은 중대한 지표들이나 또는 그 모두를 강화하기 위한 업무활동의 재설계로 이어진다. 일반적으로 BPR의 개념에는 데이터를 조직화하고, 방향을 설정하기 위하여 컴퓨터정보기술을 사용하는 것이 포함된다.

'old > 용어정리' 카테고리의 다른 글

BSRAM (Burst Static Random Access Memory)  (0) 2010.11.04
broadband ; 광대역  (0) 2010.11.04
bottleneck ; 병목현상  (0) 2010.11.04
sms  (0) 2010.07.13
1  (0) 2010.07.07
Posted by jazzlife
,

bottleneck ; 병목 현상

병목은 처리 중인 전체 프로세스가 갑자기 느려지거나 정지하는 원인이 되는 장소를 말한다. 예를 들어, 비록 ISP가 보장한 인터넷 접속속도가 56 Kbps이라도, 사용자의 모뎀이 14.4 Kbps의 속도 밖에는 낼 수 없다면, 바로 그 모뎀이 전체 성능을 떨어뜨리는 주 요인으로서, "병목" 부분이라고 생각할 수 있다. 병목이라는 단어는 병 속에 담긴 액체가 너무 빨리 나오지 않도록 하기 위해 좁게 만들어 놓은 주둥이 부분을 가리킨다. 그러나 정보기술에서의 병목 현상이란 전체 처리 과정을 느리게 만드는 경향이 있는 프로세스 내의 한 부분을 가리키는 말로 사용된다.

'old > 용어정리' 카테고리의 다른 글

broadband ; 광대역  (0) 2010.11.04
BPR (Business Process Re-engineering) ; 업무 재설계  (0) 2010.11.04
sms  (0) 2010.07.13
1  (0) 2010.07.07
Refactoring - Martin P.  (0) 2010.04.26
Posted by jazzlife
,

안드로이드 AIDL 문법(Android AIDL Syntax)

자주 받는 질문중의 하나는 “AIDL의 정확한 문법이 어떻게 되는가?” 입니다. 안드로이드의 문서에는 예제 형태로만 설명되어 있을 뿐 형식화된 문법이 제시되지 않고 있습니다. 대충 알고 대충 써라? 천만의 말씀.

 안드로이드(Android) 1.6 AIDL의 BNF Grammar 입니다. Yacc 문법을 따릅니다.

document:
        document_items
    |   headers document_items
    ;

headers:
        package
    |   imports
    |   package imports
    ;

package:
        PACKAGE
    ;

imports:
        IMPORT
    |   IMPORT imports
    ;

document_items:

    |   document_items declaration
    ;

declaration:
        parcelable_decl
    |   interface_decl
    ;

parcelable_decl:
        PARCELABLE IDENTIFIER ';'
    ;

interface_header:
        INTERFACE
    |   ONEWAY INTERFACE
    ;

interface_decl:
        interface_header IDENTIFIER '{' interface_items '}'
    ;

interface_items:

    |   interface_items method_decl
    ;

method_decl:
        type IDENTIFIER '(' arg_list ')' ';'
    |   ONEWAY type IDENTIFIER '(' arg_list ')' ';'
    ;

arg_list:

    |   arg
    |   arg_list ',' arg
    ;

arg:
        direction type IDENTIFIER
    ;

type:
        IDENTIFIER
    |   IDENTIFIER ARRAY
    |   GENERIC
    ;

direction:

    |   IN
    |   OUT
    |   INOUT
    ;

PARCELABLE, INTERFACE, IN, OUT, INOUT, ONEWAY 는 각각 키워드(Keyword) parcelable, interface, in, out, inout, oneway를 뜻하고, IMPORT, PACKAGE 는 각각 import, package 문장 전체를 뜻합니다. ARRAY 는 하나 이상의 []를 뜻하고, GENERIC 은 Collection<Object,String>과 같은 Java Generic 표현을 뜻합니다. IDENTIFIER 는 대략 Java 의 클래스 명으로 쓸 수 있는 문자열이라고 보시면 됩니다. 주석 관련 구문 요소들은 생략했습니다.
SDK 의 AIDL 설명에는 나오지 않지만, oneway 키워드를 인터페이스 또는 메쏘드 앞에 붙일 수 있음을 알 수 있습니다. One-way call 에 대한 설명은 android.os.IBinder.FLAG_ONEWAY 에 대한 SDK 문서에 등장합니다. 비록 AIDL 에서의 사용법을 설명하고 있지는 않지만, 메쏘드 실행이 끝나기를 기다리지 않고 호출 즉시 복귀하는 방법을 제공하고 있음을 알 수 있습니다. AIDL 에서 oneway 로 지정한 메쏘드들의 Proxy 는 모두 transact() 를 호출할 때 FLAG_ONEWAY 를 포함하게 됩니다. 인터페이스에 oneway 를 지정하면 모든 메쏘드에 oneway 를 지정한 효과가 발생합니다. 다중 배열은 지원되는 반면 인터페이스 계승은 지원되지 않음을 확인할 수 있습니다.

'old > Basic' 카테고리의 다른 글

Android Flow Diagram  (0) 2010.07.06
JNI  (0) 2010.07.06
Android Bitmap Object Resizing Tip  (0) 2010.07.06
Handler  (0) 2010.07.06
aidl  (0) 2010.07.06
Posted by jazzlife
,

설정항 용량에 맞게 더미 파일 만들기(fsutil file createnew)

더미 파일을 만들고 싶으시면 아래와 같이 하시면 됩니다.

fsutil file createnew 경로 용량(사이즈)

예)   fsutil file createnew c:\파일명.zip 10000

Posted by jazzlife
,

정규표현식 정리

old/JAVA 2010. 8. 25. 15:03
PHP 정규표현식 정리  

글쓴이 : 오렌지블루
  저작권자 이메일 :

출처 : codelib.co.kr
  작성일 : 2002/03/02 11:54:16

  
정규표현식이라고 불리우는 Regular expression 에 대한 phpbuilder.com 의 포럼부분 을 토대로 첨삭된 문서이다. 대부분의 프로그래밍에서 많이 필요로 하는 정규표현식 의 간략한 문법에 대해 소개하고 있다.
------------------------------------------------------------
------------------------------------------------------------

정규표현식 (Regular expression)

--------------------------------------------------------------------------------
정규표현식 (Regular 예pression)

정규표현식은 문자열의 일정한 패턴을 찾던지 치환하여 주는 기능을 가지고 있다.
메일 주소검사라던지, 소수점 몇째자리 까지 끊어서 보여주기 등.. 더욱더 복잡한
문자열도 이 정규표현식으로 처리할수 있다....
이는 프로그램시에 많은 일을 쉽게 처리하여 준다 (대부분 내장함수에도 있네요...)
특히 웹에서는 폼값을 처리할때 특정폼의 형식이 원하는 형식에 맞는지 검사할때
많이 쓰일수 있다. 정규표현식은 거의 모든 언어에서 지원하지만 사용법은 조금씩
다르다. 하지만 크게 다르지 않으므로 익혀놓으면 많은 도움이 되리라 생각된다.

**아래의 글은 몇가지 문서를 참고하였으며 정규표현식의 모든것을 포함하지는
않는다. (기본은 phpbuilder.com의 컬럼란의 내용이다)
============================================
편의상 반말을 한것에 대하여 양해를 구합니다.
============================================

정규표현식은 보통 eregi, eregi_replace, ereg, ereg_replace, 또는 perl 의 함수패턴을
그대로 사용할수 있도록 해놓은 함수 preg_match, preg_split, preg_quote 등의 함수
를 사용한다. (아마 perg 는 php 버전이 3.0.9 이상에서 사용가능할겁니다)

예) 사과라는 문자열을 배라는 문자열로 치환한다.
$string ="이것은 사과 입니다";
ereg_replace("사과","배",$string);


1. ^ 와 $ 의 사용의 예

'^' 는 바로 문자뒤의 문자열로 시작 됨을 가르킨다.
"^The" : 는 "The"로 시작 하는 문자를 말한다.

'$' 는 문자열의 맨 마지막을 가르킨다.
"of despair$" : 는 "of despair"로 끝나는 문자열이다.

"^abc$" : 는 hello로 시작해 hello로 끝나는 경우 이므로 "abc" 만 해당된다..


2. '.' '*' '+' '?' 의 사용법

'.' 은 어떤 문자든지 임의의 한문자를 말한다.꼭 하나의 문자가 있어야 한다.
예) "x.z" 는 xyz, xxz, xbz 등이고 xz난 xyyz는 안된다.

'*' 는 바로 앞의 문자가 없거나 하나 이상의 경우를 말한다.
예) "ab*" 는 a, abc, ab, abbbb 등을 말한다.

'+' 는 바로 앞의 문자를 나타내면 꼭 1나 이상이어야 한다.
예) "ab+" 는 abc, abbb 등이고 a는 되지 않는다.

'?' 는 바로 앞의 한문자가 있거나 없는것을 말한다. 단지 한문자 만이어야 한다.
예) "ab?" 는 a 또는 ab 를 나타낸다.


3. [], {} 와 () 그리고 |

3-1 '[]' 는 [] 안에 존재하는 문자들중 한 문자만을 나타낸다.
예) [abc] 는 a 또는 b 또는 c 중에 한문자를 나타낸다. 여기서 '-'를 사용할땐 범위를 나타낸다.
즉 [ a-f ] 는 [abcdf] 와 같은것을 나타낸다.
문자클래스 오퍼레이터라는 것에 대해 잠시..
유사한 성격의 문자들을 사용자가 알아보기 쉽게 단어로 그룹을 지었다고 보면 된다.

alnum : 알파벳과 숫자
alpha : 알파벳
blank : 스페이스나 탭 (시스템에 의존적임)
cntrl : 아스키코드에서의 127 이상의 문자와 32 이하의 제어문자
(한글의 첫째바이트가 127 이상이므로 제어문자로 취급됨 :()
digit : 숫자
graph : 스페이스는 제외되고 나머지는 'print' 항목과 같음.
lower : 소문자
print : 아스키코드에서 32에서 126까지의 찍을 수 있는 문자
punct : 제어문자도 아니고 알파벳.숫자도 아닌 문자
space : 스페이스, 케리지 리턴, 뉴라인, 수직 탭, 폼피드
upper : 대문자
xdigit : 16진수, 0-9, a-f, A-F

[[:alnum:]]은 [a-zA-Z0-9] 와 같은 의미다.
[[:alpha:]]은 [a-zA-Z] 와 같은 의미다.
문자열 오퍼레이터는 [] 사이에서만 효력을 발휘한다.
그리고 반대의 의미도 가능하다.
[^[:alnum:]] 은 알파벳과 숫자의 조합이 아닌것을 말한다.
[^a-zA-Z0-9] 와 같이 사용될수도 있다.



'3-2 {}'는 {} 앞에 있는 문자나 문자열의 개수를 정하는 것이다.

예) "ab" 는 "abb"를 나타낸다. 즉 b의 개수가 2개를 나타낸다.
"ab{2,}" 는 abb, abbbbb 등 b의 개수가 2개 이상을 나타낸다.
"ab{3,5}" 는 abbb, abbbb, abbbbb 와 같이 b가 3개에서 5개 까지를 나타낸다.


3-3 '()' 는 ()안에 있는 글자들을 그룹화 한다.

예) a(bc)* 는 a, abc abcbc 등 'bc'가 없거나 하나 이상인 경우이다.
"a(bc)" 는 abcbc 를 나타낸다.


3-4 '|' 는 OR 연산자 기능을 한다.

"a|b" 는 a 또는 b 둘중 하나를 나타낸다.

참고할것은 기호인데 이것은 . (, ) 등 단지 다음에 오는것이 문자라는것을
의미한다. 어떤한 처리도 없이 문자로만 인식한다.
{1,3} 하고 하면 {1,3} 와는 다르다.

4. 기초 활용

"a(bc)*" 는 a라는 문자를 포함하고 bc라는 문자열이 없거나 계속반복되는 문자열이다.
이것은 a, abc ,abcbc abcbcbc.... 등의 문자열을 의미한다.

"a(bc){1,5}" 는 a 라는 문자를 포함하고 bc 라는 문자를 묶은 형태인데. bc 라는 문자가
한번에서 5번까지를 말한다. --말이 더 어렵다....
이것은 abc,abcbc,abcbc,abcbcbc,abcbcbcbc,abcbcbcbcbc 의 문자열을 의미한다.

^[1-9][0-9]*$ 는 자연수를 표시할수 있다.
^(0|[1-9][0-9]*)$ 는 0을 포함하는 자연수
^(0|-?[1-9][0-9]*)$ 정수표시
^[0-9]+(.[0-9]+)?$ 소숫점 표시
^[0-9]+(.[0-9])?$ 소수점 둘째자리 까지
^[0-9]+(.[0-9]{1,2})?$ 소수점 둘째자리나 첫째자리
^[0-9]{1,3}(,[0-9])*(.[0-9]{1,2})?$ 돈의 표시...
(센트까지 표시가능 예 2,200.20 : 이천이백이십센트 또는 이천이백이십전 맞나?)

5. 복합활용

5-1 메일 주소 체킹..

5-1-1 : 유저명@도메인명

유저명 : 대문자, 소문자, 숫자 그리고 '.' '-' '_' 을 가질 수있지만 . 로 시작해서는 안된다.
[_0-9a-zA-Z-]+(.[_0-9a-zA-Z]+)*
이때에는 eregi 를 사용할때까 아닌 ereg 를 사용할때이다. eregi 함수는 대소문자구분이 없다.
^[_a-z0-9-]+(.[_a-z0-9-]+)*$ eregi 함수를 사용할때...

5-1-2 : 도메인 : 유저명과 기본적으로는 같지만 _ 가 없다.
^[a-z0-9-]+(.[a-z0-9-]+)*$

5-1-3 : 메일 주소 체킹
위의 것의 조합이다.

^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*$

5-2 URL 에 http:// 붙여주기

URL 은 대문자, 소문자, 숫자 ,'.','_','=','&','?','~','@','/','+' 를 사용 할수 있다
http://([0-9a-zA-Z./@~?&=_]+) 가 된다.


$add="www.codelib.co.kr";
$pattern ="([0-9a-zA-Z./@~?&=_]+)";
$link =ereg_replace($pattern, "http://1" $add);
echo ("$link");

의 결과 $link 는 다음처럼 변경 된다.
http://www.codelib.co.kr
와 같이 된다. 참고로 1 은 첫번째 괄호안의 값을 말한다. 2는 2번째..

몇가지 복잡한 정규표현식을 풀다보면 이해하는데 도움이 될것이다 '  

출처 : koreaphp.co.kr 

[출처] PHP 정규표현식 정리 |작성자 뮤즈

-----------------------------------------------------------------------------------


Regular Expressions

  1. 문자 집합 : [] - 대괄호 사이에 찾고자 하는 문자들의 집합을 표기한다
    • 예)
      • [0-9] : 0부터 9까지의 숫자 한 문자
      • [Aa] : A 혹은 a에 대응하는 한 문자
    • "-"(하이픈)은 문자 집합인 대괄호 안에서 만 문자의 범위를 지정하는 기호로 쓰인다.
  2. 제외 문자 : ^ (캐럿) - ^기호 뒤의 문자를 제외한 문자 (집합기호 - [] - 안에서 쓰일때)
    • 예)
      • ns[^0-9] : nsx - ns다음의 x가 숫자가 아닌 한 문자에 대응
  3. 메타 문자 : 정규표현식에서 특별한 의미를 가지는 문자

    • 정규표현식에서 메타문자 및 기호문자를 찾고자하는 문자에 대응하려면 "\"(escape)를 붙혀 사용한다.

    • 모든 문자 : .(마침표) - 모든 문자에 대응되는 한 문자

    • 공백 문자 : \n, \r, \t, \f-form feed, \v-vertical tab

    • 특별한 문자 형태

      • 숫자와 숫자 아닌문자 : \d - [0-9], \D - [^0-9]

      • 영숫자 문자와 영숫자 문자가 아닌 문자 : \w - [a-zA-Z0-9_], \W - [^a-zA-Z0-9_]

      • 공백문자와 공백이 아닌문자 : \s - [\f\n\r\t\v], \S - [^\f\n\r\t\v]

      • 16진수 8진수 : \x, \0

  4. 반복찾기
    • + : 한 문자 이상 - + 기호 앞으 문자가 하나 이상 반복
    • * : 문자가 없거나 하나 이상 반복
    • ? : 문자가 없거나 하나와 대응하는 문자   예) https?// - s가 없거나 한번 있는 경우와 대응
  5. 반복회수 지정하기 : {} (중괄호) - 중괄호 앞의 문자에 대하여 반복회수 지정
    • 반복회수 지정 : {반복회수} - 저정된 회수만큼 반복하는 경우 대응
      • 예)
        • #[0-9A-Fa-f]{6} - 16진수 RGB표기
    • 최소, 최대 반복회수 지정 : {최소, 최대} - 최소번 또는 최대번만 반복되는 경우 대응, 최소값에 0과 최대값의 생략 가능
      • 예)
        • \d{1,2}[-\/]\d{1,2}[-\/]\d{2,4} - -또는 / 구분의 날짜 표기
  6. greedy와 lazy 수량자
    • 탐욕적 수량자 : +, *, {n,}
    • 게으른 수량자 : +?, *?, {n,}?
    • 예) abcd <b>xxx</b> and <b>yyy</b> efgh
      • greedy : <[Bb]>.*</[Bb]> --> <b>xxx</b> and <b>yyy</b>
      • lazy : <[Bb]>.*?</[Bb]> --> <b>xxx</b> 와 <b>yyy</b>
  7. 단어 경계 지정
    • 단어 사이의 공백 : \b - 공백문자(space)와 일치하지만 공백을 일치하는 문자로 지정하지는 않는다. (\B - \b와 반대) --> 단어 사이의 구분자로 쓰임
      • 실제 공백 문자를 찾을 때는 [ ]또는 \s를 활용한다.
    • 시작 문자 지정 : ^(캐럿) - 제외 문자와 달리 표현식의 처음에 사용되어 다음에 나오는 문자를 시작하는 문자로 지정할 수 있다.
    • 마지막 문자 지정 : $ - 앞에 나온 문자가 마지막에 일치할때
    • 다중행 모드 : (?m)
      • 지정한 문자열을 줄단위로 분리하여 표현식을 검색한다.
      • 표현식의 가장 앞에 써준다.
      • 다중행 모드 지정시 ^와 $를 지정단 문자열의 줄단위로 검색하는 것이 가능하다.
    • 예) 라인단위 주석(//) 문자로 부터 해당 라인의 끝까지
      • (?m)^//.*$
  8. 하위 표현식 : () - 괄호
    • 표현식 일부를 괄호로 묶어준다.
    • 중첩 하위 표현식 : 괄호안에 괄호...
    • or 연산자 : | - | 기호의 좌우 둘중 하나가 일치하는 경우
    • 예) 아이피 형식의 문자열
      • (\d{1,3}\.){3}\d{1,3}
      • (((\d{1,2})|(1\d{2}))|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2}))|(2[0-4]\d)|(25[0-5]))
  9. 역참조 : \1 ~ \9
    • 표현식 중 하위 표현식의 순서와 지정한 번호가 해당 하위 표현식과 일치한다.
    • 0번을 지정하면 해당 표현식 전부와 일치한다.
    • 예) html의 <H1~6>태그의 내용 찾기
      • <Hh([1-6])>.*?</Hh\1>
  10. 전방탐색과 후방탐색 : 하위표현식으로 표현
    • 전방탐색 : ?= - 지정한 전방 탐색 기호의 다음 표현식으로 부터 앞에 나오는 일치하는 문자를 찾는다.
    • 후방탐색 : ?<= - 지저한 후방 탐색 기호의 다음 표현식으로 부터 뒤에 나오는 일치하는 문자를 찾는다.
    • 예) html tag기회 내의 내용
      • (?<=<[Tt][Ii][Tt][Ll][Ee]>).*?(?=</[Tt][Ii][Tt][Ll][Ee]>)
    • 부정형 전/후방 탐색 : 전방 - ?!, 후방 - ?<!
      • 예) $로 시작하지 않는 숫자
        • \b(?!\$)\d+\b
  11. 조건 달기 : ?
    • ? 앞의 문자(표현식)가 없거나 한번 일치할때 해당하는 앞으 문자(표현식)과 일치한다.
    • 전후방 탐색(?=, ?<=)의 뒤에 나오는 표현식과 일치할때...
    • 역참조 조건 : (?(backreference)true), (?(backreference)true|false)
      • backreference는 역참조 대상의 하위 표현식이며, \를 붙이지 않고 해당 하위 표현식 순서에 해당하는 번호를 지정한다.
        • 예) IMG 태그나 이미지 태그를 싸고 있는 A태그
          • (<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*</[Aa])>)
        • 예)
          • (\()?\d{3}(?(1)\)|-)\d{3}-\d{4}
    • 전방 탐색 조건 : (?(?=condition)expressions)
      • 예)
        • \d{5}(?(?=-)-\d{4})

* 유용한 정규 표현식 예

- IP : (((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))

- URL : https?://(\w*:\w*@)?[-\w.]+(:\d+)?(/([\w/_.]*(\?\S+)?)?)?

- Email : (\w+\.)*\w+@(\w+\.)+[A-Za-z]+

- HTML 주석 : <!-{2,}.*?-{2,}>

- 주민등록번호 : \d{2}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])-[1-4]\d{6}

- 한글 : [가-힣]

- 유니코드 : \ucodenumber

Posted by jazzlife
,

make 강좌

old/make 2010. 8. 17. 17:35

3. make 강좌

3.1 머릿말

소스 한두 개로 이루어진 C/C++ 언어 교양과목 과제물을 제출하는 것이 아니라면 약간만 프로젝트가 커져도 소스는 감당할 수 없을 정도로 불어나게 되고 그것을 일일이 gcc 명령행 방식으로 처리한다는 것은 상당히 곤역스러운 일입니다.

그래서 하나의 프로젝트를 효율적으로 관리하고 일관성있게 관리하기 위하여 Makefile 이라는 형식을 사용하고 make 라는 유틸리티를 사용합니다.

여러분이 리눅스에서 소스 형태로 되어 있는 것을 가져와서 컴파일하게 되면 보통 마지막에는 make 라는 명령, 또는 make <어쩌구> 이런 식으로 치게 됩니다.

make 라는 유틸리티는 보통 현재 디렉토리에 Makefile 또는 makefile 이라는 일정한 규칙을 준수하여 만든 화일의 내용을 읽어서 목표 화일(target)을 만들어냅니다. Makefile의 이름을 다르게 명시하고 싶을 때는 다음과 같이 합니다.

        $ make -f Makefile.linux

보통 멀티플랫폼용 소스들은 Makefile.solaris, Makefile.freebsd, Makefile.hp 이런 식으로 Makefile 을 여러 개 만들어두는 경향이 있지요. 또는 적절하게 만들어두어 다음과 같이 make <플랫폼> 라는 식으로 하면 컴파일되도록 하기도 합니다.

        $ make linux

이런 일은 보통의 관례일 뿐이죠. 더 예를 들어보자면 이런 식입니다. 우리가 커널 컴파일 작업할 때를 보십시요.

        $ make config           /* 설정 작업을 한다 */
        $ make dep              /* 화일 의존성을 검사한다 */
        $ make clean            /* 만든 화일들을 지우고 
                                   깨긋한 상태로 만든다 */
        $ make zImage           /* zImage(압축커널)를 만든다 */
        $ make zlilo            /* 커널을 만들고 LILO를 설정한다 */
        $ make bzImage          /* bzImage(비대압축커널)를 만든다 */
        $ make modules          /* 커널 모듈을 만든다 */
        $ make modules_install  /* 커널 모듈을 인스톨한다 */

복잡한 것같아도 우리는 항상 make, make, make ... 일관성있게 make 라고만 쳐주면 됩니다. ^^ 분량이 작은 소스들의 경우에는 일반적으로 다음만 해도 되는 경우가 많죠.

        $ make  또는 make all
        $ make install

영어권에 사는 사람들에게는 더욱 친밀하게 느껴질 겁니다. 그렇겠죠? ``만들라!''라는 동사를 사용하고 있는 것이고 그 다음에는 그들의 정상적인 어순에 따라 목적어가 나오죠.

        $ make install.man

또한 관례상 ``맨페이지'' 같은 것은 별도로 인스톨하도록 배려하는 경우가 많습니다. 프로그램에 대해 잘 아는 사람이라면 맨페이지를 자질구레하게 설치하고 싶지 않을 때도 많으니까요.

다른 사람에게 공개하는 소스라면 더욱 make 를 사용해야 합니다. 그들뿐 아니라 여러분 자신도 make 라고만 치면 원하는 결과가 나올 수 있도록 하는 것이 좋습니다. 많은 소스를 작성하다 보면 여러분 스스로도 까먹기 쉽상입니다.

일단 make를 사용하는 일반적인 관례를 익히는 것이 중요하다고 봅니다. 리눅스 배포판 패키지만 설치하지 마시고 적극적으로 소스를 가져다 컴파일해보십시요. 실력이든 꽁수든 늘기 시작하면 여러분은 더욱 행복해지실 수 있습니다. =)

3.2 make 시작해 봅시다.

일관성있게 make라고만 치면 모든 일이 술술 풀려나가도록 하는 마술은 Makefile이라는 것을 어떻게 여러분이 잘 만들어두는가에 따라 결정됩니다. 바로 이 Makefile 을 어떻게 만드는지에 대하여 오늘 알아봅니다.

상황 1)

        $ gcc -o foo foo.c bar.c

여기서 foo 라는 실행화일은 foo.c, bar.c 라는 2 개의 소스로부터 만들어지고 있습니다.

여러분이 지금 계속 코딩을 하고 있는 중이라면 이 정도쯤이야 가상콘솔 또는 X 터미널을 여러 개 열어두고 편집하면서 쉘의 히스토리 기능을 사용하면 그만이지만 하루 이틀 계속 해간다고 하면 곤역스러운 일이 아닐 수 없습니다.

자, 실전으로 들어가버리겠습니다. vi Makefile 해서 만들어봅시다. ( 편집기는 여러분 마음 )


 foo:   foo.o bar.o 
        gcc -o foo foo.o bar.o

 foo.o: foo.c
        gcc -c foo.c

 bar.o: bar.c
        gcc -c bar.c

입력하는데 주의하실 것이 있습니다. 자, 위 화일을 보십시요. 형식은 다음과 같습니다.


 목표:  목표를 만드는데 필요한 구성요소들...
        목표를 달성하기 위한 명령 1
        목표를 달성하기 위한 명령 2
        ...

Makefile은 조금만 실수해도 일을 망치게 됩니다.

맨 첫번째 목표인 foo 를 살펴보죠. 맨 첫 칸에 foo: 라고 입력하고 나서 foo가 만들어지기 위해서 필요한 구성요소를 적어줍니다. foo가 만들어지기 위해서는 컴파일된 foo.o, bar.o 가 필요합니다. 각 요소를 구분하는데 있어 콤마(,) 같은 건 사용하지 않고 공백으로 합니다.

중요! 중요! 그 다음 줄로 넘어가서는 <탭>키를 누릅니다. 꼭 한 번 이상은 눌러야 합니다. 절대 스페이스키나 다른 키는 사용해선 안됩니다. 목표 화일을 만들어내기 위한 명령에 해당하는 줄들은 모두 <탭>키로 시작해야 합니다. Makefile 만들기에서 제일 중요한 내용입니다. <탭>키를 사용해야 한다는 사실, 바로 이것이 중요한 사실입니다.

foo를 만들기 위한 명령은 바로 gcc -o foo foo.o bar.o 입니다.

다시 한 번 해석하면 이렇습니다. foo 를 만들기 위해서는 foo.o와 bar.o가 우선 필요하다.( foo: foo.o bar.o )

일단 foo.o, bar.o 가 만들어져 있다면 우리는 gcc -o foo foo.o bar.o 를 실행하여 foo 를 만든다.

자, 이제부터 사슬처럼 엮어나가는 일만 남았습니다.

foo를 만들려고 하니 foo.o와 bar.o 가 필요합니다!

그렇다면 foo.o는 어떻게 만들죠?


 
 foo.o: foo.c
        gcc -c foo.c

바로 이 부분입니다. foo.o는 foo.c를 필요로 하며 만드는 방법은 gcc -c foo.c입니다.

그 다음 bar.o 는 어떻게 만들죠?


 bar.o: bar.c
        gcc -c bar.c

이것을 만들려면 이것이 필요하고 그것을 만들기 위해서는 또 이것이 필요하고...

소스를 만들어서 해봅시다.

  • foo.c 의 내용

extern void bar ( void );

int
main ( void )
{
  bar ();
  return 0;
}

  • bar.c 의 내용

#include <stdio.h>

void
bar ( void )
{
  printf ( "Good bye, my love.\n" );
}

Makefile을 위처럼 만들어두고 그냥 해보죠.

        $ make 또는 make foo
        gcc -c foo.c
        gcc -c bar.c
        gcc -o foo foo.o bar.o

명령이 실행되는 순서를 잘 보십시요. 여기서 감이 와야 합니다. ^^

        $ ./foo
        Good bye, my love.

다시 한 번 실행해볼까요?

        $ make
        make: `foo' is up to date.

똑똑한 make는 foo를 다시 만들 필요가 없다고 생각하고 더 이상 처리하지 않습니다.

이번에는 foo.c 를 약간만 고쳐봅시다. return 0; 라는 문장을 exit (0); 라는문장으로 바꾸어보죠. 그리고 다시 한 번 다음과 같이 합니다.

        $ make
        gcc -c foo.c
        gcc -o foo foo.o bar.o

자, 우리가 원하던 결과입니다. 당연히 foo.c 만 변화되었으므로 foo.o 를 만들고 foo.o가 갱신되었으므로 foo도 다시 만듭니다. 하지만 bar.c는 아무변화를 겪지 않았으므로 이미 만들어둔 bar.o 는 그대로 둡니다.

소스크기가 늘면 늘수록 이처럼 똑똑한 처리가 필요하지요.

        $ rm -f foo
        $ make
        gcc -o foo foo.o bar.o

이것도 우리가 원하던 결과입니다. foo 실행화일만 살짝 지웠더니 make는 알아서 이미 있는 foo.o, bar.o 를 가지고 foo 를 만들어냅니다. :)

상황 2) 재미를 들였다면 이번에는 청소작업을 해보기로 합시다.


 clean:
        rm -f foo foo.o bar.o

이 두 줄을 위에서 만든 Makefile 뒷부분에 추가해보도록 합시다.

        $ make clean
        rm -f foo foo.o bar.o
        $ make
        gcc -c foo.c
        gcc -c bar.c
        gcc -o foo foo.o bar.o

make clean이라는 작업 또한 중요한 작업입니다. 확실히 청소를 보장해주어야 하거든요.

make, make clean 이런 것이 되면 상당히 멋진 Makefile 이라고 볼 수 있죠? 이번 clean 에서 보여드리고자 하는 부분은 이런 것입니다.

우리의 머리 속에 clean 이라는 목표는 단지 화일들을 지우는 일입니다.

clean: 옆에 아무런 연관 화일들이 없지요?

그리고 오로지 rm -f foo foo.o bar.o 라는 명령만 있을 뿐입니다. clean이라는 목표를 수행하기 위해 필요한 것은 없습니다. 그러므로 적지 않았으며 타당한 make 문법입니다.

상황 3)


 all: foo

이 한 줄을 Makefile 맨 앞에 넣어두도록 합시다.

        $ make clean
        $ make all
        gcc -c foo.c
        gcc -c bar.c
        gcc -o foo foo.o bar.o

이번예는 all 이라는 목표에 그 밑에 나오는 다른 목표만이 들어있을 뿐, 아무런 명령도 없는 경우입니다. 보통 우리는 make all 하면 관련된 모든 것들이 만들어지길 원합니다.

 all: foo1 foo2 foo3
 foo1: <생략>
 foo2: <생략>
 foo3: <생략>

이런 식으로 해두면 어떤 장점이 있는지 알아봅시다.

보통 make all 하면 foo1, foo2, foo3가 모두 만들어집니다. 그런데 어떤 경우에는 foo1만 또는 foo2만을 만들고 싶을 때도 있을 겁니다. 괜히 필요없는 foo3 같은 것을 컴파일하느라 시간을 보내기 싫으므로 우리는 단지 다음과 같이만 할 겁니다.

        $ make foo1
        $ make foo2

물론 일반적으로 다 만들고 싶을 때는 make all 이라고만 하면 됩니다.

make all 이건 아주 일반적인 관례이지요. 그리고 외우기도 쉽잖아요?

3.3 꼬리말 규칙, 패턴 규칙

잘 관찰해보시면 어쩌구.c -----------> 어쩌구.o 라는 관계가 매번 등장함을 알 수 있습니다. 이것을 매번 반복한다는 것은 소스 화일이 한 두 개 정도일 때야 모르지만 수십 개가 넘게 되면 정말 곤역스러운 일이라고 하지 않을 수 없지요.

다음과 같은 표현을 Makefile 에서 보는 경우가 많을 겁니다.


 .c.o:
        gcc -c ${CFLAGS} $<

여기서 .c.o 의 의미를 생각해보겠습니다. ".c 를 입력화일로 받고 .o 화일을 만든다"

        gcc -c ${CFLAGS} $<

이 문자을 보면 일단 눈에 띄는 것은 ${CFLAGS}라는 표현과 $< 라는 암호와도 같은 표현입니다. 여기서는 일단 $< 라는 기호의 의미를 알아보겠습니다.

유닉스에서 쉘을 잘 구사하시는 분들은 눈치채셨을 겁니다. 작다 표시(<)는 리다이렉션에서 입력을 의미하는 것을 아십니까? 그렇다면 $< 는 바로 .c.o 라는 표현에서 .c 즉 C 소스 화일을 의미합니다.

예를 들어 foo.c 가 있다면 자동으로

        gcc -c ${CFLAGS} foo.c

가 수행되며 gcc 에 -c 옵션이 붙었으므로 foo.o 화일이 만들어질 것입니다.

3.4 GNU make 확장 기능

.c.o 라는 전통적인 표현 말고 GNU 버전( 우리가 리눅스에서 사용하는 것은 바로 이것입니다 )의 make 에서 사용하는 방법을 알아봅시다.

위에서 예로 든 것을 GNU 버전의 make 에서 지원하는 확장문법을 사용하면 다음과 같습니다.


 %.o: %.c
        gcc -c -o $@ ${CFLAGS} $<

그냥 설명 전에 잘 살펴보시기 바랍니다.

우리가 위에서 알아보았던 표준적인 .c.o 라는 꼬리말 규칙(Suffix rule)보다 훨씬 논리적이라는 것을 발견하셨습니까?

우리가 바로 전 강의에서 main.o : main.c 이런 식으로 표현한 것과 같은 맥락이지요? 이것을 우리는 패턴 규칙(Pattern rule)이라고 부릅니다. 콜론(:) 오른쪽이 입력 화일이고 왼쪽이 목표 화일입니다. 화일명 대신 퍼센트(%) 문자를 사용한 것만 유의하면 됩니다. 여기서 foo.c 라는 입력화일이 있다면 % 기호는 foo 만을 나타냅니다.

        gcc -c -o $@ ${CFLAGS} $<

라는 표현을 해석해봅시다. ( 후  마치 고대 문자판을 해석하는 기분이 안드십니까? ^^ )

$< 는 입력화일을 의미하고 $@ 은 출력화일을 의미합니다. .c.o와 같은 꼬리말 규칙과 별 다를 바 없다고 생각하실 지 모르나 -o $@ 를 통하여 .o 라는 이름 말고 전혀 다른 일도 해낼 수 있습니다.

다음 예는 그냥 이런 예가 있다는 것만 한 번 보아두시기 바랍니다.


 %_dbg.o: %.c
        gcc -c -g -o $@ ${CFLAG} $<

 DEBUG_OBJECTS = main_dbg.o edit_dbg.o

 edimh_dbg: $(DEBUG_OBJECTS)
        gcc -o $@ $(DEBUG_OBJECTS)

%_dbg.o 라는 표현을 잘 보십시요. foobar.c 라는 입력화일(%.c)이 있다면 % 기호는 foobar 를 가리키므로 %_dbg.o 는 결국 foobar_dbg.o 가 됩니다.

기호정리

 $<     입력 화일을 의미합니다. 콜론의 오른쪽에 오는 패턴을 치환합니다.
 $@     출력 화일을 의미합니다. 콜론의 왼쪽에 오는 패턴을 치환합니다.
 $*     입력 화일에서 꼬리말(.c, .s 등)을 떼넨 화일명을 나타냅니다.

역시 GNU 버전이라는 생각이 들지 않으시는지요?

3.5 매크로(Macro) 기능

앞에서도 잠깐씩 나온 ${CFLAGS} 라는 표현을 보도록 합시다.

gcc 옵션도 많이 알고 make을 능수능란하게 다룰 수 있는 사람들은 다음과 같이 해서 자신의 프로그램에 딱 맞는 gcc 옵션이 무엇인지 알아내려고 할 것입니다.

 $ make CFLAGS="-O4"
 $ make CFLAGS="-g"

이제 매크로에 대한 이야기를 나눠볼까 합니다. 이 이야기를 조금 해야만 위의 예를 이해할 수 있다고 보기 때문입니다. 그냥 시험삼아 해보십시다. 새로운 것을 배우기 위해서는 꼭 어떤 댓가가 와야만 한다는 생각을 버려야겠지요?


 myprog: main.o foo.o
        gcc -o $@ main.o foo.o

이것을 괜히 어렵게 매크로를 이용하여 표현해보기로 하겠습니다.


 OBJECTS = main.o foo.o
 myprog: $(OBJECTS)
        gcc -o $@ $(OBJECTS)

여러분은 보통 긴 Makefile을 훔쳐 볼 때 이런 매크로가 엄청나게 많다는 것을 보신 적이 있을 겁니다. ^^


 ROOT = /usr/local
 HEADERS = $(ROOT)/include
 SOURCES = $(ROOT)/src

예상하시듯 위에서 HEADERS는 당연히 /usr/local/include가 되겠지요?

다음과 같은 문장도 있습니다.


 ifdef XPM
     LINK_DEF = -DXPM
 endif

  $ make XPM=yes

이렇게 하면 ifdef   endif 부분이 처리됩니다.

자, make CFLAGS="-O" 이런 명령을 한 번 봅시다. ${CFLAGS}에서 {} 표현은 유닉스 쉘에서 변수값을 알아낼 때 쓰는 표현입니다. CFLAGS 값을 여러분이 Makefile에 고정적으로 집어넣지 않고 그냥 make 만 실행하는 사람에게 선택권을 주기 위해서 사용하거나 자기 스스로 어떤 옵션이 제일 잘 맞는지 알아보기 위해서 사용합니다. 다른 옵션으로 컴파일하는 것마다 일일이 다른 Makefile을 만들지 말고 가변적인 부분을 변수화하는 것이 좋습니다.

3.6 마지막 주의 사항


 target:
        cd obj
        HOST_DIR=/home/e 
        mv *.o $HOST_DIR

하나의 목표에 대하여 여러 명령을 쓰면 예기치 않은 일이 벌어집니다. 기술적으로 말하자면 각 명령은 각자의 서브쉘에서 실행되므로 전혀 연관이 없습니다. -.- cd obj 도 하나의 쉘에서 HOST_DIR=/home/e도 하나의 쉘에서 나머지도 마찬가지입니다. 각기 다른 쉘에서 작업한 것처럼 되므로 cd obj 했다 하더라도 다음번 명령의 위치는 obj 디렉토리가 아니라 그대로 변함이 없이 현재 디렉토리입니다. 세번째 명령에서 HOST_DIR 변수를 찾으려 하지만 두번째 명령이 종료한 후 HOST_DIR 변수는 사라집니다.


 target:
        cd obj ; \
        HOST_DIR=/hom/e ; \
        mv *.o $$HOST_DIR

이렇게 적어주셔야 합니다. 세미콜론으로 각 명령을 구분하지요. 처음 두 줄의 마지막에 쓰인 역슬래쉬(\) 문자는 한 줄에 쓸 것을 여러 줄로 나누어 쓴다는 것을 나타내고 있습니다.

주의! 세번째 줄에 $HOST_DIR이 아니라 $$HOST_DIR인 것을 명심하십시요. 예를 하나 들어보죠. ^^


 all:
         HELLO="안녕하세요?";\
         echo $HELLO

Makefile의 내용을 이렇게 간단하게 만듭니다.

 $ make
 HELLO="안녕하세요?";\
 echo ELLO
 ELLO
<verb>

 우리가 원하는 결과가 아니죠?

 $HELLO를 $$HELLO로 바꾸어보십시요.

<verb>
 $ make
 HELLO="안녕하세요?";\
 echo $HELLO
 안녕하세요?


 all:
         @HELLO="안녕하세요?"; echo $$HELLO

명령의 맨 처음에 @ 문자를 붙여봅시다.

 $ make
 안녕하세요?

3.7 잠시 마치면서

Makefile에 대한 내용은 이것보다 훨씬 내용이 많습니다. 하지만 모든 것을 다 알고 시작할 수는 없겠지요? 이 정도면 어느 정도 충분하게 창피하지 않을 정도의 Makefile을 만들 수 있습니다.

참고로 autoconf/automake라고 하는 아주 훌륭한 GNU make 유틸리티를 시간나면 배워보시는 것도 좋습니다.

시간을 내서 리눅스에서의 C 프로그래밍에 필요한 다른 여러 가지 유틸리티들( 간접적이든 직접적이든 grep, awk, rcs, cvs 등 )의 간단/실전 사용법도 올려드릴까 생각 중입니다. ^^

'old > make' 카테고리의 다른 글

gcc 강좌  (0) 2010.08.17
gcc 소개  (0) 2010.08.17
Posted by jazzlife
,

gcc 강좌

old/make 2010. 8. 17. 17:35

2. gcc 강좌

2.1 gcc 에 대한 기본 이해

명령행 상태에서 다음과 같이 입력해봅시다. 여러분이 사용하같고 있는 gcc 버전은 알아두고 시작하셔야겠죠?

 [yong@redyong yong]$ gcc -v
 Reading specs from /usr/lib/gcc-lib/i386-linux/2.7.2.1/specs
 gcc version 2.7.2.1
 [yong@redyong yong]$ 

gcc -v 이라고 입력하니까 ``Reading specs from..'' 이라같고 말하면서 그 결과값을 ``gcc version 2.7.2.1''이라고 말해주고 있습니다. 자, 어디서 gcc 에 대한 정보를 읽어오는지 봅시다.

  /usr/lib/gcc-lib/i386-linux/2.7.2.1/specs

gcc 를 여러분이 소스를 가져다 손수 설치해보신 적은 없을 것입니다. 보통은 바이너리 패키지로 된 것을 가져다 설치하지요. 나중에 정말 휴일에 너무 심심하다 싶으면 gcc 의 소스를 가져와서 컴파일해보십시요. 참, 재미있는 경험이 될 것입니다. 이미 여러분이 갖고 있는 gcc 를 가지고 새로운 gcc 를 컴파일하여 사용합니다. C 컴파일러를 가지고 새 버전의 C 컴파일러를 컴파일하여 사용한다! 이런 재미있는 경험을 또 어디서 해보겠습니까?

gcc 패키지가 어떤 것으로 구성되어 있는지.. gcc 가 제대로 설치되어 있는지 알아보면 좋겠죠?

다음과 같습니다.

 /lib/cpp       -----------> /usr/lib/gcc-lib/i386-linux/2.7.2.1/cpp ( 링크임 )
 /usr/bin/cc    -----------> gcc ( 링크임 )
 /usr/bin/gcc                C 컴파일러 ``front-end''
 /usr/bin/protoize
 /usr/bin/unprotoize
 /usr/info/cpp.info-*.gz     GNU info 시스템을 이용하는 화일들
 /usr/info/gcc.info-*.gz                        
 /usr/lib/gcc-lib

마지막 /usr/lib/gcc-lib 디렉토리에 아래에 gcc 에 관한 모든 내용이 설치됩니다.

보통 다음과 같은 디렉토리 구조를 가집니다.

        /usr/lib/gcc-lib/<플랫폼>/< gcc 버전 >

보통 우리는 리눅스를 i386 ( 인텔 환경 )에서 사용하고 있으므로 다음과 같이 나타날 것입니다.

        /usr/lib/gcc-lib/i386-linux/2.7.2.1

( i386-linux, i486-linux, i586-linux 는 각기 다를 수 있습니다. 하지만 상관없는 내용입니다. 미친 척 하고 다른 이름을 부여할 수도 있습니다. )

그럼 계속 해서 /usr/lib/gcc-lib 밑의 내용을 살펴보죠.

 /usr/lib/gcc-lib/i386-linux/2.7.2.1/cc1
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/cpp
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/include/*.h
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/libgcc.a
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/specs

cc1이 진짜 C 컴파일러 본체입니다. gcc 는 단지 적절하게 C 인가, C++ 인가 아니면 오브젝티브 C 인가를 검사하고 컴파일 작업만이 아니라 ``링크''라는 작업까지 하여 C 언어로 프로그램 소스를 만든 다음, 프로그램 바이너리가 만들어지기까지의 모든 과정을 관장해주는 ``조정자'' 역할을 할 뿐입니다.

C 컴파일러는 cc1, C++ 컴파일러는 cc1plus, 오브젝티브 C 컴파일러는 cc1obj 입니다. 여러분이 C++/오브젝티브 C 컴파일러를 설치하셨다면 cc1plus, cc1obj 라는 실행화일도 찾아보실 수 있을 겁니다. cpp 는 "프리프로세서"입니다. #include 등의 문장을 본격적인 cc1 컴파일에 들어 가기에 앞서 먼저(pre) 처리(process)해주는 녀석입니다.

참고로 g++ 즉 C++ 컴파일러( 정확히는 C++ 컴파일러 프론트 엔드 )에 대한 패키지는 다음과 같습니다.

 /usr/bin/c++   --------------------------->    g++ 에 대한 링크에 불과함
 /usr/bin/g++
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/cc1plus    ( 진짜 C++ 컴파일러 )

오브젝티브 C 컴파일러 패키지는 다음과 같습니다.

 /usr/lib/gcc-lib/i386-linux/2.7.2.1/cc1obj
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/include/objc/*.h
 /usr/lib/gcc-lib/i386-linux/2.7.2.1/libobjc.a

구성요소가 어떤 것인지 아셨으니 좀 도움이 되셨을 겁니다.

2.2 gcc 사용하기

hello.c 라는 지긋지긋한 소스 하나를 기준으로 설명합니다 ^^


#include <stdio.h>

int
main ( void )
{
  (void) printf ( "Hello, Linux Girls! =)\n" );
  return 0;
}

참고로 제일 간단한 소스는 다음과 같은 것입니다. ^^


main () {}

컴파일을 해보겠습니다! $ 는 프롬프트이지 입력하는 것이 아닌 것 아시죠?

 $ gcc hello.c
 $

무소식이 희소식이라... gcc <C소스 화일명> 이렇게 실행하고 나서 아무런 메시지도 나오지 않고 다음 줄에 프롬프트만 달랑 떨어지면 그것이 바로 컴파일 성공입니다.

여러분은 무심코 다음과 같이 결과 프로그램을 실행시키려 할 것입니다.

 $ hello
 bash: hello: command not found
 $

예. 땡입니다. ^^

여러분은 다음과 같이 실행시켜야 합니다.

 $ ./a.out

맨 앞의 도트 문자(.)는 현재 디렉토리를 의미합니다. 그 다음 디렉토리 구분 문자 슬래쉬(/)를 쓰고 유닉스 C 에서 ``약속한'' C 컴파일러의 출력 결과 바이너리 화일인 a.out 을 써줍니다.

이러한 습관은 아주 중요합니다. 여러분이 현재 디렉토리에 어떤 실행 화일을 만들고 나서 테스트를 해 보려고 한다면 꼭 ./<실행 화일명> 이라고 적어줍니다.

유닉스는 기본적으로 PATH 라는 환경변수에 있는 디렉토리에서만 실행화일을 찾을 뿐입니다. 만약 PATH 라는 환경변수에 현재 디렉토리를 의미하는 도트 문자(.)가 들어있지 않으면 현재 디렉토리의 실행화일은 절대 실행되지 않습니다. 게다가 현재 디렉토리를 PATH 환경 변수에 넣어준다 할 지라도 도스처렁럼 현재 디렉토리를 먼저 찾는다든지 하는 일은 없습니다. 오로지 PATH 에 지정한 순서대로 수행합니다.

실행 바이너리명이 계속 a.out 으로 나오면 좀 곤란하죠. 뭐 물론 mv 명령으로 a.out 의 이름을 바꾸면 되지만서도...

-o 옵션

-o 옵션( 소문자 o 임! )은 출력(output) 화일명을 정하는 옵션입니다. 위에서 우리는 hello.c 라는 소스를 가지고 일반적으로 hello 라는 이름의 실행화일을 만들고 싶어할 것입니다.

 $ gcc -o hello hello.c
       ^^^^^^^^

또는 다음과 같이 순서를 바꿔도 무방합니다.

 $ gcc hello.c -o hello
               ^^^^^^^^

워낙 유닉스 쪽은 명령행 방식이 전통적으로 주된 방식이라 명령행에서 하는 일은 뛰어납니다.

당연히 실행을 하려면 ./hello 라고 하셔야 합니다. 결과는 다음처럼 나오겠지요?

 $ ./hello
 Hello, Linux Girls! =)
 $

주의

제일 안좋은 습관 중 하나가 바로 테스트용으로 만든 소스라고 다음처럼 하는 것입니다.

 $ gcc -o test test.c
 $ test
 $

문제를 알아내기 위하여 위에서 작성한 hello.c 를 컴파일/링크해봅시다.

 $ gcc -o test hello.c
 $ test
 $

원하는 문자열이 출력되지 않았습니다. -.-

 $ ./test
 Hello, Linux Girls! =)
 $

-c 옵션

어떤 이유로 오로지 컴파일(compile) 작업만 하고 싶은 경우가 있습니다. 그럴 때는 다음과 같이 합니다.

 $ gcc -c hello.c
 $

그 결과 만들어지는 화일은 전통적으로 hello.c 에서 .c 부분을 떼어내고 .o 를 붙인 화일입니다. 오브젝트 화일, 목적 화일이라고 하지요.

hello.o 라는 화일이 만들어집니다.

여러분은 C 언어로 조금이라도 복잡한 프로그램을 만들기 시작하면 여러 개의 소스로 나누어서 전체 프로그램을 짜게 됩니다. 그럴 때는 각 소스가 전체 기능에 기여하는 특정 기능의 함수들을 가지게 되고 오로지 한 녀석만 main 함수를 가집니다.

만약 어떤 프로그램이 foo.c, bar.c 이렇게 두 개의 소스로 이루어져 있다고 합시다. 이럴 때는 다음과 같이 하는 것이 가능합니다.

방법(1)

 $ gcc -o baz foo.c bar.c
 $ ./baz
방법(2)

 $ gcc -c foo.c
 $ gcc -c bar.c

          또는
 
 $ gcc -c foo.c bar.c
 $ gcc -o baz foo.o bar.o
              ^^^^^^^^^^^
 $ ./baz

위에서 보면 "아니! C 컴파일러에 .c 즉 소스 화일이 아닌 오브젝트 화일도 막 써주나?"라는 생각을 하시게 될 겁니다.

그렇습니다! 왜냐? gcc 는 정확히 말해서 C 컴파일러가 아닙니다. gcc 라는 실행 화일 자체는 "C 컴파일러를 돌리는 녀석"입니다.

더욱 더 정확히 말해보겠습니다.

C 언어는 기본적으로 두 가지 과정을 거쳐야만 실행화일을 만들어냅니다.

  1. 컴파일 ( .c -------> .o )
  2. 링크 ( .o -------> 실행화일 a.out )

1. 과정을 실제로 맡는 것은 cc1 이라는 녀석이고 2. 과정을 맡는 것은 ld 라는 링커(linker)입니다.

gcc 는 상당히 편리한 도구로서 .c, .o 등의 화일명 꼬리말을 보고 적절하게 C 컴파일러와 링커를 불러다가 원하는 실행화일을 만들어줍니다. gcc 는 "컴파일러와 링커를 불러주는 대리인"입니다.

hello.c 를 괜히 어렵게 컴파일/링크해봅시다 ^^

 $ gcc -c hello.c
          ^^^^^^^
 $ gcc -o hello hello.o
                ^^^^^^^

gcc 가 얼마나 똑똑피한 놈인지 알아보죠.

 $ gcc -c hello.o

이게 무슨 의미가 있겠습니까? ^^

 gcc: hello.o: linker input file unused since linking not done

위와 같이 불평합니다. 링크 과정을 수행하지 않으므로 링커에 대한 입력 화일인 hello.o 를 사용하지 않았다!

-I 옵션

#include 문장에서 지정한 헤더 화일이 들어있는 곳을 정하는 옵션입니다. 아주 많이 사용되는 옵션 중 하나입니다.


 #include <stdio.h>
 #include "my_header.h"

전자( <> 문자를 쓴 경우 )는 시스템 표준 헤더 디렉토리인 /usr/include를 기준으로 화일을 찾아서 포함시킵니다. 표준 디렉토리이지요.

후자( "" 문자를 쓴 경우 )는 지금 컴파일러가 실행되고 있는 현재 디렉토리를 기준으로 헤더 화일을 찾습니다.

이 두 디렉토리가 아닌 곳에 대해서는 명시적으로 -I<디렉토리> 로 정해줍니다.

 $ gcc -c myprog1.c -I..
 $ gcc -c myprog1.c -Iinclude

첫번째는 헤더 화일이 현재 소스 하위 디렉토리(..)에 있다는 뜻이며 두번째는 현재 디렉토리의 include라는 디렉토리에 들어있다는 뜻입니다.

-I 옵션은 얼마든지 여러번 쓸 수 있으며 주어진 순서대로 헤더 화일을 검색합니다.

주의

디렉토리명은 -I 라는 문자 바로 다음에 붙여서 씁니다. 즉 -I <디렉토리>라는 식이 아니라 -I<디렉토리> 입니다. 또한 유닉스에 있어 표준 헤더 화일 디렉토리는 /usr/include 라는 사실을 기억하시기 바랍니다. 또한 리눅스에 있어서는 커널 소스가 아주 중요한데 리눅스 고유의 기능을 쓰는 리눅스용 프로그램의 경우에는 /usr/include/linux, /usr/include/asm, /usr/include/scsi (최신 커널의 경우) 라는 디렉토리가 꼭 있어야 하며 각각은 커널 소스의 헤더 디렉토리에 대한 링크입니다. 따라서 커널 소스를 꼭 설치해두셔야 합니다.

 /usr/include/linux   -------------->  /usr/src/linux/include/linux
 /usr/include/asm     -------------->  /usr/src/linux/include/asm  
 /usr/include/scsi    -------------->  /usr/src/linux/include/scsi

( 위에서 /usr/src/linux/include/asm은 사실 대부분의 경우 /usr/src/linux/include/asm-i386 이라는 디렉토리에 대한 링크입니다 )

각각 linux는 일반적인 C 헤더 화일, asm은 각 아키텍쳐별 의존적인 어셈블리 헤더 화일, 맨 마지막은 SCSI 장치 프로그래밍에 쓰이는 헤더 화일이 들어있는 곳입니다.

일반적으로 커널 소스( 약 6 메가 이상되는 소스 )는 /usr/src 에서 tar, gzip으로 풀어두는 것이 관례입니다.

맨 처음 프로그래밍을 할 때는 그렇게 많이 쓰지는 않는 옵션이지만 여러분이 다른 소스를 가져다 컴파일할 때 아주 많이 보게 되는 옵션이므로 일단 이해는 할 수 있어야겠죠?

-l 옵션과 -L 옵션

옵션을 제대로 이해하기에 앞서 ``라이브러리''라는 것에 대한 이야기를 먼 저 하지 않으면 안될 듯 하군요.

  • 라이브러리


       ``라이브러리(Library)''라는 것은 개념상 영어 단어 그대로입니다.
      무엇인가 유용한 지식을 한 곳에 모아둔 곳이라는 개념이지요.

       C 프로그래밍을 하다 보면 반복적으로 사용하게 되는 함수들이 있기
      마련이고 그것은 하나의 함수로 떼내어 어디에서든 유용하게 사용할
      수 있도록 합니다.

       이 함수가 극도로 많이 사용되는 경우에는 ``라이브러리''라는 것으
      로 만들어두고 매번 컴파일해둘 필요없이 가져다 사용할 수 있도록
      하지요.

       라이브러리에 대한 얘기는 다음 번에 또 하게 되겠지만 일단 지금
      필요한 지식만 쌓기로 하겠습니다.

       일반적으로 관례상 라이브러리는 화일명 끝이 .a 로 끝납니다.
      여기서 a 는 Archive 라는 의미일 것입니다.

       라이브러리의 예를 들어보도록 하죠. 지금 /usr/lib 디렉토리를 한
      번 구경해보십시요. 정말로 많은 라이브러리들이 있지요.

      libc.a
      libm.a
      libdb.a
      libelf.a
      libfl.a
      libg++.a
      libg.a
      libncurses.a
      libreadline.a
      libvga.a
      등등...

       이러한 라이브러리는 우리가 컴파일 과정을 거쳐서 만든 .o 화일을
      한 곳에 통들어 관리하는 것에 불과합니다. 따라서 archive 를 의미
      하는 .a 라고 이름을 짓게 된 것이죠. 라이브러리는 ``도서관''으로
      서 그냥 .o 를 무작위로 집어넣은 것은 아니고 당연히 도서관에는
      소장하고 있는 책에 대한 목록(index)을 가지듯 포함되어 있는 .o
      에 대한 인덱스(index)를 가지고 있습니다.

       라이브러리는 다음과 같이 구성되어 있다고 할 수 있는 것입니다.

            라이브러리 = 목차(index) + ( a.o + b.o + c.o + ... )
        
       libc.a 를 가지고 한 번 놀아볼까요? 라이브러리 아카이브를 관리하
      는 ar 이라는 GNU 유틸리티를 써보겠습니다.

      $ cd /usr/lib
      $ ar t libc.a
      assert-perr.o
      assert.o
      setenv.o
      ftime.o
      psignal.o
      mkstemp.o
      sigint.o
      realpath.o
      cvt.o
      gcvt.o
      ctype-extn.o
      ctype.o
      <등등... 계속>

      $ ar t libc.a | grep printf
      iofprintf.o
      ioprintf.o
      iosprintf.o
      iovsprintf.o
      iovfprintf.o
      printf_fp.o
      vprintf.o
      snprintf.o
      vsnprintf.o
      asprintf.o
      vasprintf.o
      printf-prs.o
      reg-printf.o
      $

       위에서 볼 수 있다시피 .o 화일들이 그 안에 들어있습니다.

       <주목>
       유닉스에서 라이브러리 이름은 lib 로 시작합니다.

간단하게 라이브러리를 하나 만들어서 사용해보도록 합시다.

이번 예제는 3 개의 화일로 이루어졌습니다.

        myfunc.h
        myfunc.c
        hello.c

첫번째 myfunc.h 헤더 화일의 내용입니다.


extern void say_hello ( void );

두번째 myfunc.c, 실제 함수 정의부입니다.


#include <stdio.h>
#include "myfunc.h"

void 
say_hello ( void )
{
  printf ( "Hello, Linux guys!\n" );
}

마지막으로 메인 함수(main)가 들어있는 hello.c 입니다.


#include "myfunc.h"

int
main ( void )
{
  say_hello ();
  return 0;
}

main 함수에서 say_hello 라는 함수를 사용하게 됩니다. 이 정도야 그냥 이렇게 해버리고 말죠 ^^

 $ gcc -o say_linux hello.c myfunc.c

하지만 라이브러리를 만들어보고 시험해보려고 하는 것이므로 일부러 어렵게 한 번 해보기로 하겠습니다.

 $ gcc -c myfunc.c
 $ ar r libmylib.a myfunc.o
 $ ar s libmylib.a
 $ ar t libmylib.a
 myfunc.o
 $ gcc -o say_linux hello.c -lmylib
                            ^^^^^^^^
 ld: cannot open -lmylib: No such file or directory

흠... 처음부터 만만치 않죠? ^^ 실패하긴 했지만 몇 가지를 일단 알아봅시다.

-l 옵션

링크(link)할 라이브러리를 명시해주는 옵션이 바로 -l ( 소문자 L ) 옵션입니다.

-I 옵션과 마찬가지로 바짝 붙여서 씁니다. 절대 떼면 안됩니다.

우리는 libmylib.a 라는 라이브러리를 만들어두었습니다. 그것을 사용하기 위해서는 -lmylib 라고 적어줍니다. 라이브러리 화일명에서 어떤 글자들을 떼내고 쓰는지 주목하십시요.

 libmylib.a
    ^^^^^  

앞의 lib 를 떼내고 맨 뒤에 붙는 .a 를 떼냅니다.

링크(link)라는 것이 어떤 것이 모르신다면 당장 C 프로그래밍 책을 다시 읽어보시기 바랍니다. 이 글에서 설명할 범위는 아닌 듯 합니다.

-L 옵션

ld 는 유닉스에서 사용되는 링커(Linker)입니다. C 프로그램 컴파일의 맨 마지막 단계를 맡게 되지요.

위에서 우리는 다음과 같은 에러 메세지를 만났습니다.

 ld: cannot open -lmylib: No such file or directory

자, 이제 배워야 할 옵션은 ``라이브러리의 위치를 정해주는'' -L ( 대문자 L ) 옵션입니다. 사용형식은 -L<디렉토리명> 입니다.

리눅스에서 어떤 라이브러리를 찾을 때는 /lib, /usr/lib, /usr/local/lib와 같은 정해진 장소에서만 찾게 되어 있습니다. 그것은 규칙이지요.

중요한 사실은 아무리 여러분 라이브러리를 현재 작업 디렉토리에 놓아두어도 ld 는 그것을 찾지 않는다는 사실입니다. ld 더러 라이브러리가 있는 장소를 알려주려면 다음과 같이 -L 옵션을 붙이십시요.

 $ gcc -o say_linux hello.c -lmylib -L.
                                    ^^^

-L. 은 현재 디렉토리에서 라이브러리를 찾으라는 말입니다. -L 옵션은 여러번 줄 수 있습니다.

성공적으로 컴파일되었을 겁니다.

 $ ./say_linux
 Hello, Linux guys!

지금까지 여러분은 gcc 옵션 중 두번째로 중요한 -I, -l, -L 옵션에 대하여 배우셨습니다. 그리고 또한 라이브러리 만들기에 대하여 맛보기를 하였습니다.

'old > make' 카테고리의 다른 글

make 강좌  (0) 2010.08.17
gcc 소개  (0) 2010.08.17
Posted by jazzlife
,

gcc 소개

old/make 2010. 8. 17. 17:34

1. 시작하면서

1.1 C 와 gcc 와의 관계

세상에서 제일 뛰어난 C 컴파일러 중 하나인 gcc 는 리눅스나 기타 자유 운영체제에 있어 커다란 보배가 아닐 수 없습니다. 우리가 알고 있는 유닉스가 C 언어로 거의 다 만들어졌듯이 리눅스의 모국어는 바로 gcc 입니다.

사실 많은 분들이 리눅스 해커(hacker), 구루(guru)의 경지가 되고 싶어합니다. 그렇게 되길 원하신다면 리눅스용의 모국어인 gcc 를 익히십시요. gcc 를 알면 리눅스를 아는 것이나 다름 없습니다. 사실 C 와 유닉스가 따로 떨어진 것이 아니라 어떻게 보면 일심동체라고 할 수도 있듯이 gcc 와 리눅스는 일심동체라고 봐도 무방합니다.

C 언어! 이는 유닉스와 심지어 마이크로소프트 제품에 이르기까지(어떤 식으로 변질되었든 간에 ) 컴퓨터 세상의 ``만국 공통어''입니다. 여태까지 이러한 언어의 통일을 이뤄낸 것은 C 언어밖에 없습니다. 컴퓨터 언어의 에스페란토어를 지향하는 많은 언어들( 자바, 티클/티케이 )이 나오고 있으나 이는 두고 볼 일입니다. 그리고 그 언어를 구사한다 할 지라도 C 언어는 역시나 ``기초 교양 언어''입니다.

여러분은 리눅스에서 gcc 를 통하여 그 동안 도스/윈도 환경에서 배운 엉터리 C 언어를 잊으셔야 합니다. 감히 말하건데 그것은 C 언어가 아닙니다. C 언어는 만국 공통어야 함에도 불구하고 몇몇 회사들, 도스/윈도와 같은 환경에서 변질되어 각 환경마다 ``새로운 문법''을 배워야 하는 어처구니없는 사태가 벌어졌습니다. 터보 C 와 MS-C를 배우면서 혼란도 많았고 그 뒤에 나온 녀석들은 완전히 다른 놈들이나 다름 없습니다.

지금 리눅스에서 여러분은 C 언어의 ``정통 소림권법''을 익히실 수 있습니다. 기초가 없이 비법만 전수받아 보았자 다른 곳에 가면 수많은 비법을 지닌 무림고수들에게 여지없이 깨지기 마련입니다. 하지만 아무리 괴로와도 처음에 물 길어오는 것, 마당 쓰는 일부터 시작하면 철통같은 신체를 단련하기 때문에 온갖 꽁수 비법으로는 여러분을 헤칠 수 없습니다. 또한 정통 권법을 연마한 사람은 기본기가 갖춰져 있으므로 대련 중에도 상대의 비법을 금방 간파하고 심지어 상대의 비법만마저 자신의 것으로 하기도 합니다. ^^

1.2 gcc 에 대한 이야기 하나

gcc 는 GNU 프로젝트에 의해 만들어진 작품의 하나로서 그 명성은 하늘을 찌를 듯합니다. GNU 프로젝트응의 산물 중 가장 멋진 것을 꼽으라면 저는 주저하지 않고 C 컴파일러의 최고봉인 gcc 를 지목할 것입니다.

실제로 gcc 의 명성은 뛰어나며 수많은 상용 회사도 스폰서를 해주고 있다는 것을 아시는지요? 예를 들어 넥스트사( 지금은 사라짐 )의 새로운 C 언어인 ``오브젝티브 C''는 gcc 를 가져다 만든 것이며 FSF 측에 다시 기증 되었습니다.

gcc 는 아주 강력합니다! 이미 상용 유닉스에 달려오는 AT&T 스타일, BSD 스타일의 C 언어 문법은 물론 ANSI C 를 기본으로 하여 모든 문법을 소화해낼 수 있으며 특유의 문법도 가지고 있습니다. 아주 구식 컴파일러, 아주 구식 문법도 소화해낼 수 있습니다. 이미 많은 사람들이 상용 유닉스에도 gcc 를 설컴치하여 사용하는 경우가 많지요. ( 물론 금전적인 문제가 많이 작용 ^^ )

gcc 는 매우 단순합니다. 어떤 의미로 이런 말을 하는가 하면, 터보 C/볼랜드 C 통합환경이나 윈도 환경의 비주얼한 환경을 제공하지 않는다는 것입니다. -.- 그들이 상당히 오토매틱한 성격을 갖는 반면, gcc 는 오로지 수동 스틱방식입니다. 각각의 장단점이 있지만 여러분이 일단 gcc 를 만나시려면 각오는 하고 계셔야 합니다. 도스/윈도에서 보던 것을 원하지 마십시요. gcc 는 껍데기에 신경쓸 겨를조차 없습니다. gcc 는 오로지 명령행 방식만을 제공합니다. 그리고 그 자체로 파워풀합니다. 개발 방향은 계속 ``뛰어난 능력''이지 겉모양 화장은 아닐 것입니다. ( 만약 겉모양을 원하신다면 그것은 여러분의 몫입니다. xwpe 같은 것이 그 좋은 예라고 할 수 있습니다 )

gcc 는 어떻게 보면 C 언어에 대한 개념이 서지 않는 사람에게는 무리인 C 컴파일러인 듯 합니다. 기초 지식없이 사용한다는 것은 불가능에 가깝습니다. 하지만 C 언어를 확실하게 기초부터 배워서 어디서든 쓰러지지 않는 무림고수가 되기 위해서는 gcc 를 권합니다. 자잘한 무공을 하는 깡패가 되느냐? 아니면 정신을 지닌 무림고수가 되느냐?는 여러분의 선택에 달렸습니다.

gcc 가 어렵기만 한가? 하면 그렇지는 않습니다. gcc 는 상당한 매력을 지니고 있습니다. 그 매력으로 인해 한 번 빠지면 다른 컴파일러가 상당히 우습게 보이기까지 합니다. ( 그렇다고 다른 컴파일러를 비웃지는 마세요 ^^ 그거 쓰는 사람들이 자존심 상해서 엄청 화를 낼 테니까요. 개인적으로 생각하기에 gcc 에 대적할 수 있을 정도되는 컴파일러는 와콤 C 컴파일러 정도? )

gcc 를 배우시려면 정신 무장(?)이 중요하다고 생각해서 이렇게 장황하게 읊었습니다. 심플하게 배우면서 여러분의 리눅스, C 컴파일러에 대한 두려움을 하나씩 없애고 C 언어 위에 군림하시기 바랍니다.

자, 이제는 잡담없이 시작합니다.

'old > make' 카테고리의 다른 글

make 강좌  (0) 2010.08.17
gcc 강좌  (0) 2010.08.17
Posted by jazzlife
,

 

 

C++ 수업 090804~090807#

 

090804-TUE#

 

1장#

cout<<출력1<<"출력2string"<<출력3;

std::cout<<"출력";   // :: 공간지정 연산자

  • std 영역안에 있는 cout 을 사용

 

함수 오버로딩 Function Overloading#


 

 

동일한 함수명 중복하여 사용, 매개변수가 다르므로 구분

동일한 함수명 (매개변수1)

동일한 함수명 (매개변수1, 매개변수2)

 

  1. #include <iostream>
  2. int function(int a=10)                          // int a=10은 파라미터가 없는 경우로, 함수의 지역변수 a에 디폴트값인 10을 입력한다.{
        return a+1;
    }
    int function(void)                              // void는 값이 없는 경우로 함수의 정의가 모호해짐{
        return 10;
    }
    int main(void)
    {
        //std::cout<<function(10)<<std::endl;            // 결과 11    std::cout<<function(11)<<std::endl;            // 결과 12    //std::cout<<function()<<std::endl;           // ambiguous! 모호해짐    return 0;
    }

 

인-라인화#

  • C에서는 Macro함수

    • 전처리기에 의해 처리
    • 실행 속도의 향상
    • 구현의 어려움
  • C++에서는 inline 선언에 의한 함수의 인-라인화

    • 컴파일러에 의해서 처리
    • 실행 속도의 향상
    • 구현 용이성
    • 컴파일러에게 최적화의 기회 제공

 

이름공간 Namespace#

namespace std {            // 선언

cout;

cin;

endl;                              // endline

}

using namespace std;      // 사용

 

2장 키워드#

 

const키워드#

 

자료형 bool#

C언어에는 1과 0으로 true, false를 구분

C++에는 논리적인 참과 거짓을 의미하는 키워드 true나 fasle를 사용 , 데이터타입 bool로 선언하여 사용

데이터 타입 bool result;    

result = true;

 

레퍼런스 Reference#

 

int val=10;

int *val=&val;               // &는 val의 주소값을 의미

int &ref = val;               // &는 val의 Reference를 선언하는 의미

 

  1. #include <iostream>
  2. using std::cout;
    using std::endl;
  3. int main(void)
    {
        int val=10;
        int &ref=val;
  4.     val++;
        cout<<"ref : "<<ref<<endl;
        cout<<"val : "<<val<<endl;
  5.     ref++;
        cout<<"ref : "<<ref<<endl;
        cout<<"val : "<<val<<endl;
  6.     return 0;
    }

 

  • 레퍼런스의 제약

    • 초기화?
  • 레퍼런스를 이용한 Call by Reference

    • 포인터 연산을 할 필요가 없으므로 안정적

      • 데이터의 복사 연산이 필요 없다.
    • 원본 데이터의 손실 예상 - const 선언!

      • function (const char* name);         // 함수내에서 name을 변경할 수 없도록 한다.

 

new 와 delete#

Cpp에서                                                                      C에서

int *val = new int;                                                         int *val = (int*)malloc(sizeof(int));

int *val = new int[size];                                                int *val = (int*)malloc(sizeof(int*size));

 

delete val;

delete []arr;

 

  • NULL 포인터 리턴하는 new 연산자

 

  1. #include <iostream>
  2. using std::cout;
    using std::endl;
  3. int& increment(int &val){
        val++;
        return val;
    }
  4. int main(void)
    {
        int n=10;
        int &ref=increment(n);
  5.     cout<<"n : "<<n<<endl;
        cout<<"ref : "<<ref<<endl;
  6.     return 0;
    }

 

  1. /* ref_error.cpp */
    #include <iostream>
  2. using std::cout;
    using std::endl;
  3. int& function(void){
        int val=10;
        return val;
    }
  4. int main(void)
    {
        int &ref=function();
  5.     cout<<"ref : "<<ref<<endl;      //현재 결과는 10 이 나오지만, 나중에 포인터 연산을 하게 되면 error 발생
  6.     return 0;
    }

 

090805-WED #

3장 클래스#

3-1 구조체와 클래스#

 


  • 데이터 추상화 -> 클래스화 -> 인스턴스화(객체)
  • 접근 제어 : public, private, protected

 

  1. #include <iostream>
  2. using namespace std;
  3. class Counter  {
    public :    int val;                        // 멤버 변수    void Increment(void)            // 멤버 함수만이 클래스 내의 멤버 변수를 사용할 수 있다    {
        val++;
        }
    };
  4. int main(void)
    {
        Counter cnt;    cnt.val=0;    cnt.Increment();
        cout<<cnt.val<<endl;
        return 0;
    }

 

3-4 멤버 함수의 외부 정의#

  • 멤버 함수의 인-라인 화
  • 헤더 파일을 이용한 파일의 분할

 

4장 클래스의 정의#

  • 클래스

    • 캡슐화(모듈, 기능별 정의)
    • 정보 은닉
  • 클래스 객체의 생성과 소멸

    • 생성자
    • 소멸자

4-1 정보 은닉#

  • public을 사용하지 않고 private이나 protected를 사용
  • public을 사용한다는 것은 class이전의 C로 돌아가는 것임

 

4-2 캡슐화#

  • class

 

4-3 생성자와 소멸자#

  • 생성자 함수를 통한 인자 전달
  • public 생성자 : 어디서든 객체 생성 가능
  • private 생성자 : 클래스 내부에서만 가능

Person p = Person("KIM", "010-000-0000", 22);

Person p("KIM", "010-000-0000", 22);                     // 객체를 만들면서 매개 변수를 써서 함수를 호출

Person p();                                                      // 파라미터 형식을 맞춰줘야 함

 

  • 디폴트 생성자
Person(){}

 

4-4 클래스와 배열#

 

  • 객체 배열과 생성자

    • 객체를 배열로 가짐
    • 객체 배열은 기본적으로 void 생성자의 호출을 요구한다.
  • 객체 포인터 배열

    • 포인터로 배열을 가짐

 

4-5 this 포인터#

  • this 포인터의 의미

    • 클래스 자기 자신

class Point {

int aaa;

public :

 Point(int aaa)

{

this->aaa=aaa;             // this->aaa는 class의 aaa, 그냥 aaa는 public안의 aaa

}

};

 

4-6 friend 선언#

  • friend 선언의 유용성

    • 유용하지 않다
    • 정보 은닉에 위배되는 개념
    • 연산자 오버로딩에서 유용하게 사용

 

  1. #include <iostream>
  2. using std::cout;
    using std::cin;
    using std::endl;
  3. class Counter
    {
        int val;
  4. public:
        Counter() {       // 생성자 초기화
            val=0;
        }
        void Print() const{              // {블럭 안에서}값 변경 금지 const        cout<<val<<endl;
        }
        friend void SetX(Counter& c, int val);           // friend 선언};
  5. void SetX(Counter& c, int val)          // 전역 함수{   c.val=val;   }
  6. int main()
    {
        Counter cnt;
        cnt.Print();
  7.     SetX(cnt, 2002);
        cnt.Print();
        return 0;
    }

 

 

연습문제 - Linked List (C -> C++)#

  • C 에서 사용한 scanf 나 printf는 그대로 사용할 수는 있지만, 좋지 않다
  • C 에서 쓴 getch()는 C++ 에서 사용 불가 -> getche() 로 대체
  • 소멸자 함수에서 함수를 메모리에서 해제하기 위해 delete 연산자를 사용한다. 생성된 구조체를 모두 찾아서 해제시켜준다.
  • C에서 사용한 malloc 대신에 new연산자를 사용한다.
  • C에서 class를 만들어서 함수 선언을 해준다
  • C++의 main()에서 함수를 호출할 경우 class명을 붙이고 :: 공간지정연산자를 붙여서 호출한다.

이 글은 스프링노트에서 작성되었습니다.

'old > C Grammer' 카테고리의 다른 글

기억 부류  (0) 2010.11.18
함수  (0) 2010.11.17
연산자  (0) 2010.11.16
제어문  (0) 2010.11.15
변수  (0) 2010.11.12
Posted by jazzlife
,

심볼릭링크 생성

old/Linux 2010. 8. 13. 11:15

※ 리눅스에서 심볼릭링크 생성

심볼릭링크 : 다른파일(또는 디렉토리)에 대한 추상적인 위치를 가리키는 경로(Path)

하드링크 : 특정한 물리적인 데이터 경로


심볼릭링크 생성방법

$ln -s /path/to/file1.txt /path/to/file2.txt

$ls -ali


하드링크 생성방법

#ln /root/file1 /root/file2

#ls -l

 

Posted by jazzlife
,

Shape

old/UI Design 2010. 8. 10. 17:10

1.Linear Gradient


<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#FFFF00" android:endColor="#FFFFFF" android:angle="270"/>
    <corners android:radius="0dp" />
</shape>


2.Radial Gradient


<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <gradient android:type="radial"
        android:startColor="#ff0000"
        android:endColor="#ffff00"
        android:gradientRadius="300"
        android:centerX="0.5"
        android:centerY="0.7"/>
</shape>



 

3.Line


<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
    <stroke android:width="1dp" android:color="#FF000000"
            android:dashWidth="1dp" android:dashGap="2dp" />
    <size android:height="5dp" />
</shape>


4.Oval

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="#00000000"/>
    <stroke android:width="4dp" android:color="#990000FF"
            android:dashWidth="4dp" android:dashGap="2dp" />
    <padding android:left="7dp" android:top="7dp"
            android:right="7dp" android:bottom="7dp" />
    <corners android:radius="4dp" />
</shape>


5.Ring & Sweet Gradient

<shape android:shape="ring" xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadiusRatio="3"
    android:thicknessRatio="8"
    android:useLevel="false">
    <size android:width="48dip"
        android:height="48dip" />
    <gradient android:type="sweep"
        android:useLevel="false"
        android:startColor="#4c737373"
        android:centerColor="#4c737373"
        android:centerY="0.50"
        android:endColor="#ffffd300" />
</shape>

'old > UI Design' 카테고리의 다른 글

shape layout  (0) 2010.08.04
cutom title bar  (0) 2010.08.04
adb shell에서 특정 activity실행하기  (0) 2010.07.06
PowerManager에서 Screen ON/OFF 통지  (0) 2010.07.06
Resources - Menus, Searchable  (0) 2010.07.01
Posted by jazzlife
,

smb.conf 설정 예

old/Linux 2010. 8. 10. 17:05

31.5. Configuration of the /etc/smb.conf file

The /etc/smb.conf file is the main configuration file for the Samba server, in which you can specify which directory you want to access from Windows machines, which IP addresses are authorized, and so on. The first few lines of the file under the [global] line contain global configuration directives, which are common to all shares, unless they are over-ridden on a per-share basis, followed by share sections. A lot of options exist, and it's important to read the documentation that comes with Samba for more information on each of the different settings and parameters.

The following configuration example is a minimal working configuration file for Samba with encrypted password support. Also, it's important to note that we comment in this Samba configuration only parameters that relate to security and optimization, and left other posiblities for you to explore.

In our example we have created just one directory, [tmp] and have allowed only class C machine IP address ranges to connect on the Samba server. Also, we don't use print-sharing capability between Samba and Windows on this server. Edit the smb.conf file, vi /etc/smb.conf and add/change the following parameters:

      [global]

      workgroup = OPENNA
      server string = R&D of Open Network Architecture Samba Server
      encrypt passwords = True
      security = user
      smb passwd file = /etc/smbpasswd
      log file = /var/log/samba/log.%m
      socket options = IPTOS_LOWDELAY TCP_NODELAY
      domain master = Yes
      local master = Yes
      preferred master = Yes
      os level = 65
      dns proxy = No
      name resolve order = lmhosts host bcast
      bind interfaces only = True
      interfaces = eth0 192.168.1.1
      hosts deny = ALL
      hosts allow = 192.168.1.4 127.0.0.1
      debug level = 1
      create mask = 0644
      directory mask = 0755
      level2 oplocks = True
      read raw = no
      write cache size = 262144

      [homes]
      comment = Home Directories
      browseable = no
      read only = no
      invalid users = root bin daemon nobody named sys tty disk mem kmem users

      [tmp]
      comment = Temporary File Space
      path = /tmp
      read only = No
      valid users = admin
      invalid users = root bin daemon nobody named sys tty disk mem kmem users
    

This tells the smb.conf file to set itself up for this particular configuration setup with:

[global].

workgroup = OPENNA

The option workgroup specifies the workgroup your server will appear to be in when queried by clients. It's important to have the same workgroup name on both clients and servers.

server string = R&D of Open Network Architecture Samba Server

The option server string specifies the string that you wish to show to your users in the printer comment box in print manager, or to the IPC connection in the net view command under Windows machines.

encrypt passwords = True

The option encrypt passwords if set to True instructs Samba to use encrypted passwords instead of plain text password when negotiating with the client. Sniffer program will not be able to detect your password when it is encrypted. This option always must be set to True for security reasons.

security = user

The option security, if set to user, specifies that a client must first log-on with a valid username and password, or the connection will be refused. This means that a valid username and password for the client must exit in your /etc/passwd file on the Linux server and in the /etc/smbpasswd file of the Samba server, or the connection from the client will fail. See Securing samba in this chapter for more information about the smbpasswd file.

smb passwd file = /etc/smbpasswd

The option smb passwd file specifies the path to the encrypted smbpasswd file. The smbpasswd file is a copy of the /etc/passwd file of the Linux system containing valid usernames and passwords of clients allowed to connect to the Samba server. The Samba software reads this file, smbpasswd when a connection is requested.

log file = /var/log/samba/log.%m

The option log file specifies the locations and names of Samba log files. With the name extension %m, it allows you to have separate log files for each user or machine that logs on your Samba server i.e. log.machine1.

socket options = IPTOS_LOWDELAY TCP_NODELAY

The option socket options specifies parameters that you can include in your Samba configuration to tune and improve your samba server for optimal performance. By default we chose to tune the connection for a local network, and improve the performance of the Samba server for transferring files.

domain master = Yes

The option domain master specifies to set nmbd, the Samba server daemon, as a domain master browser for its given workgroup. This option usually must be set to Yes only on one Samba server for all other Samba servers on the same network and workgroup.

local master = Yes

The option local master allows nmbd, the Samba server daemon, to try to become a local master browser on a subnet. Like the above, usually this option must be set to Yes only on one Samba server that acts as a local master on a subnet for all the other Samba servers on your network.

preferred master = Yes

The option preferred master specifies and controls if nmbd the Samba server daemon, is a preferred master browser for its workgroup. Once again, this must usually be set to Yes on one server for all the others on your network.

os level = 65

The option os level specifies by its value whether nmbd, the Samba server daemon, has a chance of becoming a local master browser for the Workgroup in the local broadcast area. The number 65 will win against any NT Server. If you have an NT Server on your network, and want to set your Linux Samba server to be a local master browser for the Workgroup in the local broadcast area then you must set the os level option to 65. Also, this option must be set only on one Linux Samba server, and must be disabled on all other Linux Samba servers you may have on your network.

dns proxy = No

The option dns proxy if set to Yes specifies that nmbd, the Samba server daemon, when acting as a WINS server and finding that a Net BIOS name has not been registered, should treat the Net BIOS name word-for-word as a DNS name and do a lookup with the DNS server for that name on behalf of the name-querying client. Since we have not configured the Samba server to act as a WINS server, we don't need to set this option to Yes. Also, setting this option to Yes will degrade your Samba performance.

name resolve order = lmhosts host bcast

The option name resolve order specifies what naming services to use in order to resolve host names to IP addresses, and in what order. The parameters we chose cause the local lmhosts file of samba to be examined first, followed by the rest.

bind interfaces only = True

The option bind interfaces only if set to True, allows you to limit what interfaces will serve smb requests. This is a security feature. The configuration option interfaces = eth0 192.168.1.1 below completes this option.

interfaces = eth0 192.168.1.1

The option interfaces allows you to override the default network interface list that Samba will use for browsing, name registration and other NBT traffic. By default, Samba will query the kernel for the list of all active interfaces and use any interface, except 127.0.0.1, that is broadcast capable. With this option, Samba will only listen on interface eth0 on the IP address 192.168.1.1. This is a security feature, and completes the above configuration option bind interfaces only = True.

hosts deny = ALL

The option hosts deny specifies the list of hosts that are not permitted access to Samba services unless the specific services have their own lists to override this one. For simplicity, we deny access to all hosts by default, and allow specific hosts in the hosts allow = option below.

hosts allow = 192.168.1.4 127.0.0.1

The option hosts allow specifies which hosts are permitted to access a Samba service. By default, we allow hosts from IP class C 192.168.1.4 and our localhost 127.0.0.1 to access the Samba server. Note that the localhost must always be set or you will receive some error messages.

debug level = 1

The option debug level allows the logging level to be specified in the smb.conf file. If you set the debug level higher than 2 then you may suffer a large drop in performance. This is because the server flushes the log file after each operation, which can be very expensive.

create mask = 0644

The option create mask specifies and sets the necessary permissions according to the mapping from DOS modes to UNIX permissions. With this option set to 0644, all file copying or creating from a Windows system to the Unix system will have a permission of 0644 by default.

directory mask = 0755

The option directory mask specifies and set the octal modes, which are used when converting DOS modes to UNIX modes when creating UNIX directories. With this option set to 0755, all directory copying or creating from a Windows system to the Unix system will have a permission of 0755 by default.

level2 oplocks = True

The option level2 oplocks, if set to True, will increase the performance for many accesses of files that are not commonly written, such as .EXE application files.

read raw = no

The option read raw controls whether or not the server will support the raw read SMB requests when transferring data to clients. Note that memory mapping is not used by the read raw operation. Thus, you may find memory mapping is more effective if you disable read raw using read raw = no, like we do.

write cache size = 262144

The option write cache size allows Samba to improve performance on systems where the disk subsystem is a bottleneck. The value of this option is specified in bytes, and a size of 262,144 represent a 256k cache size per file.

[tmp].

comment = Temporary File Space

The option comment allows you to specify a comment that will appear next to a share when a client does queries to the server.

path = /tmp

The option path specifies a directory to which the user of the service is to be given access. In our example this is the tmp directory of the Linux server.

read only = No

The option read only specifies if users should be allowed to only read files or not. In our example, since this is a configuration for the tmp directory of the Linux server, users can do more than just read files.

valid users = admin

The option valid users specifies a list of users that should be allowed to login to this service. In our example only the user admin is allowed to access the service.

invalid users = root bin daemon nobody named sys tty disk mem kmem users

The option invalid users specifies a list of users that should not be allowed to login to this service. This is really a paranoid check to absolutely ensure an

Posted by jazzlife
,

git 작업취소

old/Git 2010. 8. 7. 20:30
개별파일 원복
git checkout  -- <파일> : 워킹트리의 수정된 파일을 index에 있는 것으로 원복
git checkout HEAD -- <파일명> : 워킹트리의 수정된 파일을 HEAD에 있는 것으로 원복(이 경우 --는 생략가능)
git checkout FETCH_HEAD -- <파일명> : 워킹트리의 수정된 파일의 내용을 FETCH_HEAD에 있는 것으로 원복? merge?(이 경우 --는 생략가능)

index 추가 취소
git reset -- <파일명> : 해당 파일을 index에 추가한 것을 취소(unstage). 워킹트리의 변경내용은 보존됨. (--mixed 가 default)
git reset HEAD <파일명> : 위와 동일

commit 취소
git reset HEAD^ : 최종 커밋을 취소. 워킹트리는 보존됨. (커밋은 했으나 push하지 않은 경우 유용)
git reset HEAD~2 : 마지막 2개의 커밋을 취소. 워킹트리는 보존됨.
git reset --hard HEAD~2 : 마지막 2개의 커밋을 취소. index 및 워킹트리 모두 원복됨.
git reset --hard ORIG_HEAD : 머지한 것을 이미 커밋했을 때,  그 커밋을 취소. (잘못된 머지를 이미 커밋한 경우 유용)
git revert HEAD : HEAD에서 변경한 내역을 취소하는 새로운 커밋 발행(undo commit). (커밋을 이미 push 해버린 경우 유용)

워킹트리 전체 원복
git reset --hard HEAD : 워킹트리 전체를 마지막 커밋 상태로 되돌림. 마지막 커밋이후의 워킹트리와 index의 수정사항 모두 사라짐.
                                  (변경을 커밋하지 않았다면 유용)


* 참조 : reset 옵션
--soft : index 보존, 워킹트리 보존. 즉 모두 보존.
--mixed : index 취소, 워킹트리만 보존 (기본 옵션)
--hard : index 취소, 워킹트리 취소. 즉 모두 취소.

'old > Git' 카테고리의 다른 글

Repo 설치 및 설정  (0) 2011.01.14
git 요약  (0) 2010.07.27
Subversion Git 사용법  (0) 2010.05.14
Eclipse Plugins  (0) 2010.02.01
Git과 SVN 통합  (0) 2010.02.01
Posted by jazzlife
,

shape layout

old/UI Design 2010. 8. 4. 22:06

[shape_counter.xml]

<?xml version="1.0" encoding="utf-8"?>

<!-- produced by lee.hyuntae@btbsolution.co.kr
  for text counter background     -->

<shape
 xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid
     android:color="#88000000" />
    <padding
     android:left="7dp" 
        android:right="7dp" />
    <corners
       android:radius="4dp" />

</shape>

'old > UI Design' 카테고리의 다른 글

Shape  (0) 2010.08.10
cutom title bar  (0) 2010.08.04
adb shell에서 특정 activity실행하기  (0) 2010.07.06
PowerManager에서 Screen ON/OFF 통지  (0) 2010.07.06
Resources - Menus, Searchable  (0) 2010.07.01
Posted by jazzlife
,

cutom title bar

old/UI Design 2010. 8. 4. 15:57
enter code heremy_title.xml 
<ImageView android:src="@drawable/jetpack" 
    android:layout_width="wrap_content" android:layout_alignParentLeft="true" 
    android:layout_centerVertical="true" android:id="@+id/back" 
    android:layout_height="wrap_content" android:layout_alignParentTop="true" /> 
 
<TextView android:id="@+id/title" android:layout_width="wrap_content" 
    android:gravity="center_vertical" android:textSize="20px" 
    android:textColor="#ffffff" android:layout_alignParentRight="true" 
    android:text="New Title" android:background="#a5c639" 
    android:layout_height="wrap_content" android:layout_alignParentTop="true" 
    android:padding="9dip" android:layout_margin="5dip" /> 

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title);

    ((TextView)findViewById(R.id.title)).setText("gradient shadow"); 
 
    findViewById(R.id.back).setOnClickListener(new OnClickListener() { 
        public void onClick(View v) { 
            ((TextView)findViewById(R.id.title)).setText("loce"); 
        } 
    }); 

because custom title default is fixed you should write yourself theme:

'old > UI Design' 카테고리의 다른 글

Shape  (0) 2010.08.10
shape layout  (0) 2010.08.04
adb shell에서 특정 activity실행하기  (0) 2010.07.06
PowerManager에서 Screen ON/OFF 통지  (0) 2010.07.06
Resources - Menus, Searchable  (0) 2010.07.01
Posted by jazzlife
,

git 요약

old/Git 2010. 7. 27. 18:19

# Permission Request
# If you want to join p500_froyo Project, plz follow permission process.
[Korean] http://cc.lge.com/newcc/xe/9204
[English] http://cc.lge.com/newcc/xe/12239

# Registering Public key
# 1.  $ ssh-keygen -t rsa
# 2.  $ cat ~/.ssh/id_rsa.pub  (copy contents)
# 3. log on to gerrit site http://165.243.137.39:8091/p500_froyo
# 4. Settings -> SSH Keys -> Add Key -> Paste your publick key -> Add
# 5. copy Server Host Key and register known_hosts

# 사전 설정
git config --global user.name "hong.hyunjun"
git config --global user.email "hong.hyunjun@lge.com"

# 권한 확인
# ssh -p 29439 hong.hyunjun@165.243.137.26
ssh -p 29421 hong.hyunjun@165.243.137.39
("Connection to 165.243.137.26 closed."  is OK result.)

# 로그인
# repo init -u ssh://hong.hyunjun@165.243.137.26:29439/p500/manifest.git -b lge_p500
repo init -u ssh://hong.hyunjun@165.243.137.39:29421/p500_froyo/manifest.git -b p500_froyo_master

# 최신 소스 다운로드
repo sync

# lge_gw740 <= branch 명
# git pull 및 push 가능
# repo start lge_p500 --all
repo start p500_froyo_master --all

# 소스 위치
# /home/hong.hyunjun/git/vs660/.repo/project.list 참조
cd /home/hong.hyunjun/git/p500/android/packages/apps/FmRadio

# 소스 반영 전에 build를 해주는 습관을 기르자!!
# IFmRadioControlService.java copy
# src/*
# res/*
# Android.mk
# AndroidManifest.xml

# 다수의 git 프로젝트로 구성된 경우 각 git 프로젝트를 검색하여 변경파일을 출력함
repo status

# 현재 Add / Commit 또는 새로 추가된 파일들의 목록을 보여 줌
git status

# 수정된 소스 가져오기 (push, commit 사전 절차)
git pull

# 수정된 소스를 인덱스에 올리기
git add .
git rm aaa.png
git rm . (현 폴더 모든거)
git rm -r 폴더이름(해당 폴더 전체)

# 반영된 소스 승인 ("comment")
git commit -m "20100722 fixed BroadCom Stack, bind FM_RECEIVER_SERVICE and seekStation available"
git commit -m "20100726 enable to volume control for FmRadio on Lockscreen and sleep"
git commit -m "20100726 fixed ON/OFF and modify seek thresh to 105 and add string"
git commit -m "20100726 modify ON/OFF button image"

# 수정된 소스 올리기 (수정된 소스 덮어치기)
git push

# 빌드
cd /home/kim.taejung/C710/gw740/android

# optional
make clean

# build
# make update-api
# ./build_target.sh
./build_target.sh -j16

# classes : out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar

# 변경된 file들을 Head 상태로 원복
git checkout -f

# 해당 테그로 소스 다운로드
repo forall -c git checkout P500_20100718_V08e_pre1_QCT6013
repo forall -c git checkout P500_20100720_V08e_final
repo forall -c git reset --hard P500_20100720_V08e_final
repo forall -c git reset --hard P500_20100718_V08e_pre1_QCT6013
repo forall -c git reset --hard P500_20100717_V08d_pre2_temp


adb shell
su
cat /proc/kmsg

'old > Git' 카테고리의 다른 글

Repo 설치 및 설정  (0) 2011.01.14
git 작업취소  (0) 2010.08.07
Subversion Git 사용법  (0) 2010.05.14
Eclipse Plugins  (0) 2010.02.01
Git과 SVN 통합  (0) 2010.02.01
Posted by jazzlife
,
; 핸들러로 지연시키지 않으면 안 뜬다...이상해...

Handler keyPadHandler = new Handler();
            keyPadHandler.postDelayed(new Runnable() {
                public void run() {
                    if(mRecipientsEditor!= null){
                    if(mRecipientsEditor.getVisibility()== View.VISIBLE){
                        InputMethodManager inputMethodManager =
                            (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);       
                     inputMethodManager.showSoftInput(mRecipientsEditor, 0);
                    }
                    }
                }
            }, 100);

'old > sms&mms' 카테고리의 다른 글

SMS solicite_eclair  (0) 2010.07.22
Internals of Telephony subsystem  (0) 2010.07.09
The Radio Interface Layer (RIL)  (0) 2010.07.09
Android's Radio Interface Layer(RIL)  (0) 2010.07.08
Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
Posted by jazzlife
,

SMS solicite_eclair

old/sms&mms 2010. 7. 22. 12:12
[ComposeMessageActivity.java]
confirmSendMessageIfNeeded()
sendMessage()

[WorkingMessage.java]
send()
sendSmsWorker(conv, msgText)

[SmsMessageSender.java]
sendMessage(threadId)

- frameworks
[SmsManager.java]
1.sendMultipartTextMessage(mDests[i], mServiceCenter, messages, sentIntents, deliveryIntents)
2.sendTextMessage()

[IccSmsInterfaceManager.java] - ISms.aidl (ISms_Stub.java)
권한승인 -  
PhoneBase.getContext().enforceCallingPermission("android.permission.SEND_SMS","Sending SMS message");
1.sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents)
2.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent)

[GsmSMSDispatcher.java] - extended SMSDispatcher
1.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,(ArrayList<PendingIntent>) sentIntents,
(ArrayList<PendingIntent>) deliveryIntents)
   SmsMessage.getSubmitPdu(scAddress, destinationAddress,parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader),encoding)
   sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent)

2.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent)
   SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddr, destAddr, text, (deliveryIntent != null))
   SMSDispatcher.sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent)


Posted by jazzlife
,

sms

old/용어정리 2010. 7. 13. 13:44
TPDU is an acronym for Transport Protocol Data Unit.

UCS : Universal Character Set characters
AT Command : AT 명령어의 원래 명칭은 헤이즈 명령어(Hayes command) 입니다.
미국의 헤이즈 마이크로컴퓨터(Hayes Microcomputer products)사의 스마트 모뎀 및 그 호환 모뎀을 제어하기 위하여 사용되는 명령어 랍니다.
현재 사실상의 표준으로 되어있는 거의 모든 모뎀이 사용하고 있습니다.
통상 명령어가 AT로 시작하기 때문에 AT 명령어라 불리우게 되었습니다.
여기서 AT는 "주목"의 의미를 가지는 attention의 약자 라고 합니다.

'old > 용어정리' 카테고리의 다른 글

BPR (Business Process Re-engineering) ; 업무 재설계  (0) 2010.11.04
bottleneck ; 병목현상  (0) 2010.11.04
1  (0) 2010.07.07
Refactoring - Martin P.  (0) 2010.04.26
Network  (0) 2010.03.24
Posted by jazzlife
,

Internals of Telephony Subsystem

1.1. Part I, the key items

Assumption: We are in the top level of Android source code repository

  • Files
    frameworks\base\telephony  the core of the telephony subsystem implementation, GSM phone and so on
    packages\apps\Phone        Phone application implementation, UI related stuffs reside
    hardware\ril               Radio reference implementation

  • The big picture

  • The key interfaces and classes

    1. Phone interfaces
      Phone.java:Base abstraction of the phone

      frameworks\base\telephony\java\com\android\internal\telephony\Phone.java

      PhoneBase.java:An abstract class which extends Phone interface and implements the Event registration and notification

      frameworks\base\telephony\java\com\android\internal\telephony\PhoneBase.java

      GSMPhone.java:A concrete phone implementation

      frameworks\base\telephony\java\com\android\internal\telephony\gsm\GSMPhone.java

      CommandsInterface.java:Radio operation abstraction

      frameworks\base\telephony\java\com\android\internal\telephony\gsm\CommandsInterface.java

      BaseCommands.java:Radio event registration and notification

      frameworks\base\telephony\java\com\android\internal\telephony\gsm\BaseCommands.java

      RIL.java: Radio interface library implementation, responsible for sending request to Radio layer and
      distribute the response from Radio layer to request sender
       

      frameworks\base\telephony\java\com\android\internal\telephony\RIL.java

      Native stub for RIL.java: communicates with RIL.java through local socket

      hardware\ril\libril\*

      Reference implementation of Radio library:communicates with Radio hardware through AT command

      hardware\ril\reference-ril\*

      Radio interface lib daemon runs as a stand alone process

      hardware\ril\rild\*

    2. RIL request and response
      1, Solicited and Unsolicited response
      Solicited response response to the upper layer request, this is a kind of passive response,
      for instance, response the request of Singal strength request
      Unsolicited response a response triggered by the underlying hardware, for instance, the state change
      Radio will trigger an RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED response to notify the upper layer

    3. Request sending and handling
      RIL_Sender thread
      gets the reqeust from mRequestsList and send it to Radio reference library through local socket
      RIL Receiver thread
      receives the response from Radio reference library and process it with processUnsolicited()/processSolicited()
      according to response type RESPONSE_UNSOLICITED/RESPONSE_SOLICITED
      processUnsolicited() is responsible for processing active event from Radio layer
      processSolicited() is responsible for processing passive response to upper layer request

    4. Message identity localization and Parcel
      The mechanism used here is localize the identity of message and put it into a Parcel, send it to the target,
      the target receives the Parcel, put the wanted stuffs into Parcel and return back it to the sender, it is
      the sender's responsibility to classify and handle the response corresponds to the specific request.

      We explain this trick by an example, User dialed a number
      *A user's dialing activity runs a long trip to get to the point dial() in RIL.java
      * RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
           send(rr);
           put the RIL_REQUEST_DIAL ID into Parcel embedded in rr and send it to the target, the target here is      reference-ril.c
      * refernece-ril.c receives the request and handle it with requestDial()
      * requestDial() completes it work and send response back by RIL_onRequestComplete()
      * The implementation of RIL_onRequestComplete() resides in ril.cpp
           p.writeInt32 (RESPONSE_SOLICITED);
           p.writeInt32 (pRI->token);
           put the response type to RESPONSE_SOLICITED, because the request is initiated by upper level, and it      is a passive response, put the RIL_REQUEST_DIAL into the Parcel (pRI->token == RIL_REQUEST_DIAL) for      upper layer to handle the response to the RIL_REQUEST_DIAL request.
      * thanks to the local socket, the control flow arrived at RIL.java again, this time it hits at
           RIL_Receiver(),for the reason of RIL_Receiver's listing on SOCKET_NAME_RIL socket
           the RIL_Receiver delegates the response to the processSolicited(), it was responsibility of
           processSolicited() to notify the registrarant according the content of the response.

'old > sms&mms' 카테고리의 다른 글

soft keyboard 출력 방법  (0) 2010.07.22
SMS solicite_eclair  (0) 2010.07.22
The Radio Interface Layer (RIL)  (0) 2010.07.09
Android's Radio Interface Layer(RIL)  (0) 2010.07.08
Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
Posted by jazzlife
,

The Radio Interface Layer (RIL)

Introduction

Android's Radio Interface Layer (RIL) provides an abstraction layer between Android telephony services (android.telephony) and radio hardware. The RIL is radio agnostic, and includes support for Global System for Mobile communication (GSM)-based radios.

The diagram below illustrates the RIL in the context of Android's Telephony system architecture.

Solid elements represent Android blocks and dashed elements represent partner-specific proprietary blocks.

The RIL consists of two primary components:

  • RIL Daemon: The RIL daemon initializes the Vendor RIL, processes all communication from Android telephony services, and dispatches calls to the Vendor RIL as solicited commands.
  • Vendor RIL: The radio-specific Vendor RIL of ril.h that processes all communication with radio hardware and dispatches calls to the RIL Daemon (rild) through unsolicited commands.

The RIL Shim Layer

Radio Interface Layer (RIL)

  • HAL interface between the Android TelephonyManager and the baseband modem
  • Voice, Data, SMS, SIM, SIMToolkit
  • Android includes a reference AT command based RIL

RIL API

  • Currently 75 requests (e.g. Dial) and 17 unsolicited responses (e.g. signal strength)
  • Android RIL inspired by GSM TS 27.007
  • Can implement as AT command based or proprietary protocol (e.g. RPCs via shared memory)

Enhancing the RIL

  • Carriers may require specific features (e.g. JCDMA, O2 Homezone)
  • Qualcomm working on adding CDMA and Multi-mode support

Certification

  • GCF
  • CDG

Tips

  • SIM and SIM Toolkit is complex, get an expert
  • RIL needs to provide neighboring cell id (non-standard). Used by Google Maps.
  • Data: suggest packet interface, no DHCP, no PPP.
  • Depending on modem interface, RIL may get complicated with lots of logic/state.
  • Android data is always-on, modem should support dormancy

Architecture overview

Linux手机打电话代码分析(Android) - clarkluo2004 - 天翼的博客

 
RIL
Initialization

Android initializes the telephony stack and the Vendor RIL at startup as described in the sequence below:

  1. RIL daemon reads rild.lib path and rild.libargs system properties to determine the Vendor RIL library to use and any initialization arguments to provide to the Vendor RIL
  2. RIL daemon loads the Vendor RIL library and calls RIL_Init to initialize the RIL and obtain a reference to RIL functions
  3. RIL daemon calls RIL_register on the Android telephony stack, providing a reference to the Vendor RIL functions

See the RIL Daemon source code at /device/commands/rild/rild.c for details.

RIL Interaction

There are two forms of communication that the RIL handles:

  • Solicited commands: Solicited commands originated by RIL lib, such as DIAL and HANGUP.
  • Unsolicited responses: Unsolicited responses that originate from the baseband, such as CALL_STATE_CHANGED and NEW_SMS.

Solicited

The following snippet illustrates the interface for solicited commands:

void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);

There are over sixty solicited commands grouped by the following families:

  • SIM PIN, IO, and IMSI/IMEI (11)
  • Call status and handling (dial, answer, mute…) (16)
  • Network status query (4)
  • Network setting (barring, forwarding, selection…) (12)
  • SMS (3)
  • PDP connection (4)
  • Power and reset (2)
  • Supplementary Services (5)
  • Vendor defined and support (4)

The following diagram illustrates a solicited call in Android:

Unsolicited

The following snippet illustrates the interface for unsolicited commands:

void OnUnsolicitedResponse (int unsolResponse, void *data, size_t datalen);

There are over ten unsolicited commands grouped by the following families:

  • Network status changed (4)
  • New SMS notify (3)
  • New USSD notify (2)
  • Signal strength or time changed (2)

The following diagram illustrates an unsolicited call in Android:

Implementing the RIL

To implement a radio-specific RIL, create a shared library that implements a set of functions required by Android to process radio requests. The required functions are defined in the RIL header (/include/telephony/ril.h).

The Android radio interface is radio-agnostic and the Vendor RIL can use any protocol to communicate with the radio. Android provides a reference Vendor RIL, using the Hayes AT command set, that you can use as a quick start for telephony testing and a guide for commercial vendor RILs. The source code for the reference RIL is found at /commands/reference-ril/.

Compile your Vendor RIL as a shared library using the convention libril-<companyname>-<RIL version>.so, for example, libril-acme-124.so, where:

  • libril: all vendor RIL implementations start with 'libril'
  • <companyname>: a company-specific abbreviation
  • <RIL version>: RIL version number
  • so: file extension

RIL_Init

Your Vendor RIL must define a RIL_Init function that provides a handle to the functions which will process all radio requests. RIL_Init will be called by the Android RIL Daemon at boot time to initialize the RIL.

RIL_RadioFunctions *RIL_Init (RIL_Env* env, int argc, char **argv);

RIL_Init should return a RIL_RadioFunctions structure containing the handles to the radio functions:

type structure {
	int RIL_version;
	RIL_RequestFunc onRequest;
	RIL_RadioStateRequest onStateRequest;      
	RIL_Supports supports;
	RIL_Cancel onCancel;
	RIL_GetVersion getVersion;
} 
RIL_RadioFunctions;

RIL Functions

ril.h defines RIL states and variables, such as RIL_UNSOL_STK_CALL_SETUP, RIL_SIM_READY, RIL_SIM_NOT_READY, as well as the functions described in the tables below. Skim the header file (/device/include/telephony/ril.h) for details.

RIL Solicited Command Requests

The vendor RIL must provide the functions described in the table below to handle solicited commands. The RIL solicited command request types are defined in ril.h with the RIL_REQUEST_ prefix. Check the header file for details.

void (*RIL_RequestFunc)(int request, void *data, size_t datalen, RIL_Token t);

This is the RIL entry point for solicited commands and must be able to handle the various RIL solicited request types defined in ril.h with the RIL_REQUEST_ prefix.

  • request is one of RIL_REQUEST_*
  • data is pointer to data defined for that RIL_REQUEST_*
  • t should be used in subsequent call to RIL_onResponse
  • datalen is owned by caller, and should not be modified or freed by callee

Must be completed with a call to RIL_onRequestComplete(). RIL_onRequestComplete() may be called from any thread before or after this function returns. This will always be called from the same thread, so returning here implies that the radio is ready to process another command (whether or not the previous command has completed).|

RIL_RadioState (*RIL_RadioStateRequest)();

This function should return the current radio state synchronously.

int (*RIL_Supports)(int requestCode);

This function returns “1” if the specified RIL_REQUEST code is supported and 0 if it is not.

void (*RIL_Cancel)(RIL_Token t);

This function is used to indicate that a pending request should be canceled. This function is called from a separate thread–not the thread that calls RIL_RequestFunc.

On cancel, the callee should do its best to abandon the request and call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point.

Subsequent calls to RIL_onRequestComplete for this request with other results will be tolerated but ignored (that is, it is valid to ignore the cancellation request).

RIL_Cancel calls should return immediately and not wait for cancellation.

const char* (*RIL_GetVersion)(void);

Return a version string for your Vendor RIL

The vendor RIL uses the following callback methods to communicate back to the Android RIL daemon.

void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);

* t is parameter passed in on previous call to RIL_Notification routine.

  • If e != SUCCESS, then response can be null and is ignored
  • response is owned by caller, and should not be modified or freed by callee
  • RIL_onRequestComplete will return as soon as possible

void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime);

Call user-specified callback function on the same thread that RIL_RequestFunc is called. If relativeTime is specified, then it specifies a relative time value at which the callback is invoked. If relativeTime is NULL or points to a 0-filled structure, the callback will be invoked as soon as possible.

RIL Unsolicited Commands

The functions listed in the table below are call-back functions used by the Vendor RIL to invoke unsolicited commands on the Android platform. See ril.h for details.

void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen);

* unsolResponse is one of RIL_UNSOL_RESPONSE_*

  • data is pointer to data defined for that RIL_UNSOL_RESPONSE_*
  • data is owned by caller, and should not be modified or freed by callee

The ril source code in userspace

Usefull links

'old > sms&mms' 카테고리의 다른 글

SMS solicite_eclair  (0) 2010.07.22
Internals of Telephony subsystem  (0) 2010.07.09
Android's Radio Interface Layer(RIL)  (0) 2010.07.08
Complete End to End Call Flow of Short Message Service(SMS)  (0) 2010.07.08
Android SMS call analysis  (0) 2010.07.06
Posted by jazzlife
,

Eternity74님의 블로그에서 얻은 아주 유용한 Tip!
Eternity74님 감사합니다.^^;

Source Insight로 디버깅을 하다보면, 떠있는 창이 50-60개에 육박하는 경우가 많은데,
이런 경우, Source Insight가 잡아먹는 리소스가 장난 아니다.
컴퓨터가 버벅거리기 일쑤~!
이 Tip을 적용하면, Source Insight에서 창이 10개이상이 뜨면, 오래된 창부터 자동으로 닫아준다.

이 매크로를 사용하려면,
Options > Preference > General > Enable event handler 에 체크가 되있어야 한다.
그 후, Base Project의 Utils.em파일을 열어 다음과 같은 function을 추가한다.

event DocumentOpen(sFile)
{
   nHoldWnd = 10
   winCnt = WndListCount()
   if(winCnt > nHoldWnd) {
      hWnd = GetCurrentWnd()
      while(nHoldWnd-- != 0) {
         hWnd = GetNextWnd(hWnd)
      }

      while(hWnd != 0) {
         hTmpWnd = GetNextWnd(hWnd)
         CloseWnd(hWnd)
         hWnd = hTmpWnd
      }
   }
}


event 로 시작하는 함수는 source Insight 에서 정의하는 event handler인데, DocumentOpen()이라는 함수는 새로운 파일을 open할때 불려지는 이벤트 핸들러이다.

적용해보니 잘된다. ㅎㅎㅎ
참고로 이 방법을 적용할 수 있는 Source Insight 버전은 3.50.0045 이상이어야 한다.

'etc' 카테고리의 다른 글

popJazzSmooth  (0) 2010.11.17
깡통파일(더미파일) 만들기  (0) 2010.09.01
SourceInsight 한글 주석 깨지지 않게하기  (0) 2010.07.09
Source Insight에서 Custom Language 추가하기  (0) 2010.07.09
안드로이드 참고자료  (0) 2010.07.08
Posted by jazzlife
,
설정방법
 
1. DoNoting() 이라는 macro를 만들어 추가한다. 진짜로 아무일도 하지 않는 걸로.
macro DoNothing()
{
}
2. Option > Key Assignment 을 선택한다.
 


 


 
3. Macro: DoNothing 선택후에 Assign New Key를 누르고 다음의 키조합을 입력한다.
Shift + 한/영 (황당한 조합이지만 먹힌다.)
4. 화면에 "shift+ " 로 표시되면 들어간 것이다.
 
5. 완료!!

이후로 아무 것도 해줄 필요가 없다.

그냥 메모장 쓰듯이 한글입력하면 된다. 쌍자음 그냥 입력해도 안 깨진다.

 
 
주의
"어 안되잖아?" 하시는 분이 있을까봐...
 
txt 파일에서 시험해보면 확실히 아무런 문제가 없는데, c 파일에서는 커멘트나 따옴표 블럭 밖에서는 한글이 깨진것처럼 보일 것이다.
정확한 이유는 알수 없지만 깨진게 아니고 잘못 보여주는 것이다. (syntax highlight 때문이라고 생각한다.)


아래 그림에서 보듯이, 마우스로 블럭선택해보면 멀쩡한 글자들이 보인다.

그리고 커멘트내에서는 안 깨져 보인다.

 c 파일에서 커멘트나 따옴표 외부에 한글쓸 일은 어차피 없으니 안심하자.


 


 
배경지식
 
Source Insight 로 한글입력시 shift 때문에 깨진 파일을 헥사 에디터로 보면 0xe5가 들어가면서 한글이 깨진다는 것을 알 수 있다.
그런데 0xe5가 뭐냐하면...
 
VK_PROCESSKEY (0xE5)
Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
 
그니까 소스인사이트는 IME에서 내려오는 virtual key code중에서 ctrl 이나 alt 같은 실제로 문자입력이 아닌 값을 유효한 문자인 줄 알고 처리하고 있는 것이다.
 

그래서 이걸 가로챌 방법을 생각하다가 macro hot key로 assign 해보니까.. 통했다.


be happy!!

Posted by jazzlife
,

Source Insight에서 Custom Language 추가하기

Custom Language란?

  • Source Insight에서 기본적으로 제공하는 프로그래밍 언어 외에 사용자가 새로운 언어 타입을 재정의하거나 추가할 수 있는 기능을 말합니다.
  • 가장 일반적으로 많이 사용되는 C/C++, Java 등의 언어에 대한 Language Definition은 이미 Source Insight에 포함되어 있는데, 이것들 외에 사용자가 별도로 더 추가하고 싶은 언어가 있을 수 있습니다. 이럴 때 사용하는 것이 Custom Language 기능입니다.
  • 또는 Symbian C++ 등과 같이 별도의 추가적인 파일 확장자나 parsing 규칙을 일부 사용하는 경우에 기존 Language Definition을 상속/재정의 해서 사용할 수도 있습니다.

Custom Language File 구하기

  • 기본적으로 Source Insight 공식 홈페이지에서 제공하는 Custom Language File(이하 CLF)을 사용할 수 있습니다.
  • 인터넷 검색을 통해서 몇몇 CLF 파일을 구할 수 있기도 하지만, 의외로 드뭅니다. :(
  • 사용자가 직접 CLF를 만드는 것도 가능합니다. 이 작업은 좀 번거롭고 시간이 걸릴 수 있습니다.

Custom Language 추가하기

Custom Language를 추가하는 데에는 두 가지 작업을 필요합니다. 하나는 Language 자체에 대한 parsing 정보를 등록하는 것이고, 나머지는 등록한 Language를 Project에 적용할 수 있도록 Document Option에 추가해주는 것입니다.

  1. 새로운 Language 추가하기
    1. Options 메뉴 -> Preferences 메뉴 -> Languages 탭으로 이동합니다.
      sicl1.png
    2. Import 버튼을 눌러 원하는 CLF 파일을 가져옵니다.
      Add 버튼을 눌러서 새로운 Language를 추가하고 직접 keyword 편집이나 symbol parsing 규칙 등록 등의 작업을 해줄 수도 있습니다.
      sicl2.png
    3. 이제 Languages 탭에서 새로운 Language가 추가된 것을 확인할 수 있습니다.
      ※ 사용자가 추가한 Custom Language는 아이콘이 약간 다릅니다.
      sicl3.png
  2. 추가한 Language에 대한 Document Option 추가하기
    1. Options 메뉴 -> Document Options 메뉴를 실행한 다음 다이얼로그에서 Add Type 버튼을 눌러 새로운 타입을 추가합니다.
      sicl4.png
    2. 추가된 타입에 대한 상세 설정을 해줍니다.
      sicl5.png

      1. 이 Language Type이 적용될 확장자를 지정해줍니다.
      2. Include when adding to projects 항목을 체크해주어야 프로젝트 생성 시 해당 확장자 파일이 자동으로 추가됩니다.
      3. 위 첫 번째 단계에서 추가한 Custom Language를 지정해줍니다.

Symbian C++ 개발을 위한 추천 설정

Symbian 관련 개발 상에서는 일반 C++ 개발 상에서와 달리 추가되는 파일들이 몇 가지 더 있습니다. 그렇기 때문에 이 파일들을 별도의 Language Type으로 등록해주면 소스 분석에 더욱 도움이 됩니다.

  • 가장 먼저 Symbian C++ 관련 C.tom 파일을 적용해두셔야 합니다.
  • Symbian C++ 관련 source 파일 등록
    • 추가해야 할 확장자들: *.hrh;*.pan;*.inl;*.rsg;*.rh;*.loc;*.mbg;*.rss;*.rls;*.cia
      주의: C++ Language Type에 Symbian C++ 관련 확장자를 등록해두신 분은 C++ Language Type 쪽에서 그 확장자를 제거해주실 필요가 있습니다.
      sicl6.png
  • Symbian C++ 관련 build script 파일 등록

    • 추가해야 할 확장자들: *.mmp;*.midef;*.inf;*.iby
      sicl7.png
Posted by jazzlife
,

안드로이드 참고자료

etc 2010. 7. 8. 17:26
Posted by jazzlife
,
RIL 이란 무엇인가?
 
개요.
 
안드로이드 RIL은 android.telephony 서비스들과 radio h/w간의 추상화된 계층을 제공한다.
RIL은 radio agnostic(존재하지만 정확하게 표현하기는 어려운 실체)이며, GSM 기반의 radio들에 대한 지원을 포함하고
있다.
 
아래의 그림은 안드로이드 전화통화 시스템 구조를 설명한다.
 
   
 
위의 그림에서 Radio Daemon과 Vender RIL은 파트너의 특수성을 가진 사적소유영역에 속하며, 나머지 블록은
안드로이드 영역에 속한다고 할 수 있다.
 
RIL은 두가지의 기본적인 컴포넌트로 구성된다.
 
RIL 데몬(Daemon) : 
 
RIL 데몬은 Vender RIL을 초기화하며, 안드로이드 telephony 서비스들로부터의 모든 통신을 프로세스하며,
solicited 명령어를 통해 Vender RIL로 콜을 넘긴다.
 
Vender RIL :
 
ril.h의 radio 특수성을 포함하는 Vender RIL은 radio h/w와의 모든 통신을 처리하며, unsolicited 명령어들을 통해서
RIL 데몬(rild)에 콜을 넘긴다.



 
RIL 초기화
 
안드로이드는 구동시점에 아래에 언급된 순서대로, telephony 스택과 Vender RIL 을 초기화한다.
 
1. RIL 데몬은 Vender RIL에 제공해야할 초기화 argument와 그것을 사용하기 위한 Vender RIL 라이브러리를
   결정하기 위한 rild.lib 경로와 rild.libargs 시스템 속성들을 읽어들인다.
 
2. RIL 데몬은 Vender RIL 라이브러리를 load(탑재)하며, RIL을 초기화하기 위해 RIL_Init을 호출하며,
    RIL 함수에 대한 참조를 얻는다.
 
3. RIL 데몬은 Vender RIL 함수들에 대한 하나의 참조를 제공하는 안드로이드 Telephony 스택상의  
    RIL_register를 호출한다.
 
RIL 상호작용
 
RIL 제어 관련 통신에는 두가지 형식이 존재한다.
 
Solicited commands : Solicited 명령어들은 전화걸기(DIAL) 과 HANGUP(전화끊기)와 같은 RIL 라이브러리에 의해
                                만들어 진다.
Unsolicited responses : Unsolicited responses는 CALL_STATE_CHNGED(전화 상태 변화)와 NEW_SMS(새 문자
                                   메시지)와 같은 baseband로 부터 만들어 진다.

 
Solicited
 
아래의 인용은 solicited 명령어들에 대한 인터페이스를 보여주고 있다.
 
void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);

 
그리고 아래와 같이 계열들로 묶여질 수 있는 60개 이상의 solicited 명령어들이 존재한다.
 
  • SIM PIN, IO, and IMSI/IMEI (11)
  • Call status and handling (dial, answer, mute…) (16)
  • Network status query (4)
  • Network setting (barring, forwarding, selection…) (12)
  • SMS (3)
  • PDP connection (4)
  • Power and reset (2)
  • Supplementary Services (5)
  • Vendor defined and support (4)
아래의 다이어그램은 안드로이드에서의 solicited call을 설명하고 있다.
 
 
 
Unsolicited
 
아래의 인용은 unsolicited 명령어들에 대한 인터페이스를 설명하고 있다.
 
void OnUnsolicitedResponse (int unsolResponse, void *data, size_t datalen);

 
그리고 아래와 같이 계열들로 묶여질 수 있는 10개 이상의 unsolicited 명령어들이 존재한다.
 
  • Network status changed (4)
  • New SMS notify (3)
  • New USSD notify (2)
  • Signal strength or time changed (2)
아래의 다이어그램은 안드로이드에서의 unsolicited call을 설명하고 있다.
 
 
 
RIL 구현하기
 
특정 radio RIL을 구현하기 위해서는, 라디오 요청을 처리하기 위해 안드로이드에서 요구되는 함수의 집합을 구현하는
공유 라이브러리를 만들어야 한다. 요구되는 함수들은 RIL header (/include/telephony/ril.h)에 정의된다.
 
안드로이드 radio 인터페이스는 radio-agnostic이며, Vender RIL은 radio를 통해 통신하기 위한 어떤 프로토콜도
사용할 수 있다. 안드로이드는 하나의 참조적 구현형태로써의 Vender RIL을 제공하고 있는데, 그것은 Hayes AT
command 집합을 사용하고 있으며, 여러분들은 telephony 테스트를 위한 쉬운 시작과 상업적 Vender RIL 들을 위한
가이드로써 사용할 수 있다. 참조적으로 구현된 RIL 소스 코드는 /commands/reference-ril/ 에서 볼 수 있다.
 
libril-<companyname>-<RIL version>.so 규약을 사용해서 공유 라이브러리 형태로 여러분의 Vender RIL을 컴파일
해라. 여기에 예로써, libril-acme-124.so가 있다.
  • libril: 모든 vender RIL 구현은 'libril' 로 시작
  • <companyname>: 특정 회사의 약어
  • <RIL version>: RIL 버전 숫자
  • so: 파일 확장자
RIL_Init
 
여러분의 Vender RIL은 모든 radio 요청들을 처리할 함수들에 대한 제어를 제공하는 RIL_Init 함수를 정의해야 한다.
RIL_Init은 RIL을 초기화하기 위해, 부트시점에서 안드로이드 RIL Daemon에 의해 호출된다.
 
RIL_RadioFunctions *RIL_Init (RIL_Env* env, int argc, char **argv);

 
RIL_Init은 radio 함수들에 대한 제어를 포함하는 RIL_RadioFuncions 구조체를 반환해야 한다.
 
type structure {
       int RIL_version;
       RIL_RequestFunc onRequest;
       RIL_RadioStateRequest onStateRequest;      
       RIL_Supports supports;
       RIL_Cancel onCancel;
       RIL_GetVersion getVersion;
}
RIL_RadioFunctions;

 
 
RIL 함수들
 
ril.h는 아래의 테이블에 설명된 함수들 같은, RIL_UNSOL_STK_CALL_SETUP, RIL_SIM_READY, RIL_SIM_NOT_READY 과
같은 RIL 상태들과 변수들을 정의한다. 더 상세하게는 헤더파일(/device/incldue/telephony/ril.h)을 살펴보길.
 
RIL Solicited 명령어 요청들.
 
Vender RIL은 solicited 명령어들을 처리하기 위해 아래의 테이블에 설명된 함수들을 제공해야 한다.
RIL solicited 명령어 요청 타입들은 RIL_REQUEST_ 라는 접두사를 가지고 ril.h에 정의된다.
상세하게는 헤더 파일을 체크하길.
 
함수명 설명
void (*RIL_RequestFunc) (int request, void *data, size_t datalen, RIL_Token t); 이것은 solicited 명령어들에 대한 시작 포인트이며, RIL_REQUST_ 접두사를 가지고 ril.h에 정의된 다양한 RIL solicited 요청 타입들을 제어할 수 있어야 한다.
  • request 는 RIL_REQUEST_* 중 하나임.
  • data 는 RIL_REQUST_* 위해 정의된 data에 대한 포인터임.
  • t 는 RIL_onResponse 에 수반되는 호출에서 사용되어야 함.
  • datalen 은 caller 소유이며, callee에 의해 수정되거나 free 되어서는 안됨.
RIL_onRequestComplete()에 대한 호출을 통해 완료되어야 함.
RIL_onRequestComplete()는 임의의 쓰레드로부터 이 함수의 반환 이전 또는 이후에 호출될 수 있다. 이것은 항상 동일한 쓰레드로부터 호출될 것이며, 그러므로 여기에서 반환이라함은 radio가 다른 명령을 수행할 준비하 되어있음을 의미한다.(이전 명령이 완료여부와 상관없이)
RIL_RadioState (*RIL_RadioStateRequest)(); 이 함수는 현재의 radio 상태를 동기적으로 반환해야 한다.
int (*RIL_Supports)(int requestCode); 이 함수는 명시된 RIL_REQUEST 코드가 지원된다면 "1"을 아니라면 "0"을 반환한다.
void (*RIL_Cancel)(RIL_Token t); 이 함수는 멈춰져 있는 요청을 취소시키기 위해 사용된다.
이 함수는 다른 쓰레드, 즉 RIL_RequestFunc 을 호출한 쓰레드가 아닌 쓰레드에 의해 호출된다.
 
취소시, callee는 요청을 포기하기 위해 최선을 다해야하며, 잠시후 RIL_Errno CALCELLED 를 가지고 RIL_onRequestComplete를 호출한다.
 
다른 결과들을 가진 이 요청들에 대한 RIL_onRequestComplete에 대한 수반되는 호출들은 묵인되지만, 무시된다.(그것은 취소 요청을 무시하기 위해 유효한 것이다)
 
RIL_Cancel 호출들은 즉시 반환되어야 하며, 취소를 기다려서는 안된다.
const char * (*RIL_GetVersion) (void); 여러분의 Vender RIL에 대한 버젼 문자열을 반환한다.
 
Vender RIL은 안드로이드 RIL 데몬에 역으로 통신하기 위해 다음과 같은 callback 메쏘드를 사용한다.
 
함수명 설명
void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
  • t 는 이전 호출에서 RIL_Notification 루틴에 전달된 파라메터이다.
  • 만약 e != SUCCESS 라면, response 는 null 이 될것이며, 무시된다.
  • RIL_onRequestComplete 는 가능한 빨리 return 할 것이다.
void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime); RIL_RequestFunc 이 호출된 동일한 쓰레드에서 사용자 정의의 callback 함수를 호출한다. 만약 relativeTime 이 명시되었다면, 그것은 callback이 발생해야하는 상대적인 시각을 명시한다. 만약 relativeTime 이 NULL 이거나 0 으로 채워진 구조체에 대한 포인터라면, callback은 최대한 빨리 발생한다.

 
RIL Unsolicited 명령어들
 
아래의 테이블에 열거된 함수들은 안드로이드 플랫폼에서 unsolicited 명령어들을 발생시키기 위해 Vendor RIL에 의해
사용되는 call-back 함수들이다. 자세하게는 ril.h 를 보길.
 
함수명 설명
void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen);
  • unsolResponse 는 RIL_UNSOL_RESPONSE_* 중 하나임.
  • data 는 RIL_UNSOL_RESPONSE_* 를 위해 정의된 data에 대한 포인터임.
  • data 는 caller 소유이며, callee 에 의해 수정되거나 free 되어서는 안됨.

이건 뭐 간단히 말해서 안드로이드 소프트웨어(Telephony service)와 하드웨어(Radio) 사이에 존재하는 놈(추상레이어)으로  인터페이스 역할을 한다.
  • Ex) SMS Sending/Receiving, Incomming/Outgoing call, Data, Network and so on.
  • 두가지 Command로 나눈다.

       1. Solicited : User가 요청한 command (SMS Sending, Outgoing call 등)

          - 101 개 정도 commands : (Ril_commands.h 에 정의)

       2. Unsolicited : User의 의도와 상관없이 network나 h/w에서 받는 command (SMS Retriving, Incomming call 등)

          - 31개 정도 (Ril_unsol_commands.h에 정의)

     

    getIMSI() : ril.java - {RIL_REQUEST_GET_IMSI, dispatchVoid, responseString}

    - dispatchVoid() : ril.cpp

    -- s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI); //Vendor ril

    -- RIL_onRequestComplete : ril.cpp

    ---- responseFunction() : responseString()

    ---- sendResponse(p)

    - processResponse : ril.java

    processSolicited : ril.java

     

    Posted by jazzlife
    ,
     Complete End to End Call Flow of Short Message Service(SMS)

    [ad#co-1]

     We will use above picture as refference.

    For example,  Subscriber A(MS A) want to send Short message to subscriber B(MS B)

    1.  Then subscriber A will type the message on the phone and select subscriber B as the destination address.
    2.  After subsriber A, hit send button, MS terminal will request channel assignment to the BTS and BSC and then forward the MS A Information to MSC A
    3.  MSC A will check MS A(subscriber A) data from VLR, if the telecommunication operator has many SMSC, it will identified which SMSC this MS A belong to.
    4.  After that MS A will transfer the short message to MSC A, at this point on MS A phone will display “sending…” notification
    5.  MSC A routes the message to the interworking MSC(IW MSC), beside use IW MSC usually it can use STP
    6.  IW MSC will route the short message to the SMSC.
    7.  SMSC Send a notification report to IW MSC and then to MSC A, MSC B and come to subscriber. At this point MS A phone will display “Message Sent” but not yet delivered to MS B
    8.  All Above step called MO(Message Originating), we will come on MT(Message Terminating) on the next step
    9.  SMSC Transfer the short message to the Gateway MSC(GW MSC)
    10.  The GW MSC ask information from the HLR for routing the short message
    11.  GW MSC will forward the message to MSC B, and MSC B will check MS B data from VLR
    12.  MSC B Transfer the short message to MS B through BSC and BTS
    13.  MSC B Send delivery report to GW MSC, and GW MSC will forward to HLR and SMSC. At this point MS B receive the message and can read it.
    14.  Delivery report will send by SMSC to MS A after MS B receive the message.

    Quite log story  :) . but this simple thing need so many interworking between quite alot of telecommunication network element.

    'old > sms&mms' 카테고리의 다른 글

    The Radio Interface Layer (RIL)  (0) 2010.07.09
    Android's Radio Interface Layer(RIL)  (0) 2010.07.08
    Android SMS call analysis  (0) 2010.07.06
    기본 안드로이드 서비스 구조  (0) 2010.05.12
    SMS framework 소스 참고  (0) 2010.05.10
    Posted by jazzlife
    ,

    1

    old/용어정리 2010. 7. 7. 12:09

    glibc : GNU C 라이브러리(줄여서 glibc)는 GNU 프로젝트의 일환으로 만든 C 표준 라이브러리의 한
                 종류이다.

    EABI : EABI(임베디드 응용 프로그램 이진 인터페이스, embedded-application binary
                interface)는 임베디드 소프트웨어 프로그램을 수행하는 파일 형식, 자료형, 레지스터 사
                용, 스택 프레임 조직, 명령 변수를 위한 표준 변환을 정의하고 있다.

                 EABI를 지원하는 컴파일러는 이와 같은 또다른 컴파일러가 만든 코드와 호환되는 목적코드를
                 만드므로 개발자들이 다른 컴파일러가 만들어 낸 목적 코드와 한 컴파일로로 만
                 든 라이브러리를 연결할 수 있게 한다. 자체적인 어셈블리어 코드를 작성하는 개발자
                 들은 EABI를 사용하여 호환 컴파일러가 만들어낸 어셈블리 코드와 상호 작용하게 할 수
                 있다.

                 일반 목적의 운영 체제에서 ABI와 EABI의 추된 차이점은 권한 명령이 응용 프로그램 코
                 드 내에서 실행되는 점, 동적 링크가 요구되지 않는다는 점(심지어는 아예 동적 링크를
                 허용하지 않는 경우도 있음), 메모리 저장을 위해 더 작아진 스택 프레임 조직을 갖춘다
                 는 점이 있다.[1]

                 널리 쓰이는 EABI로는 파워피씨[2]ARM 아키텍처[3][4]가 있다.
                
    primitive : 컴퓨터 프로그램 작성에서 어떤 복잡한 프로그램을 만드는 데 사용될 수 있는 언어의 가장 기본적인 
                    단위, 즉 문자, 숫자, 요소 등.

    marshalling : 마샬링은 하나 이상의 프로그램 또는 연속되어 있지 않은 저장 공간으로부터 데이터를 모은 
                          다음, 데이터들을 메시지
    버퍼에 집어넣고, 특정 수신기나 프로그래밍 인터페이스에 맞도록 그 
                          데이터를 조직화하거나, 미리 정해진 다른 형식으로 변환하는 과정을 말한다.


    Daemon (computer software): a background process

    'old > 용어정리' 카테고리의 다른 글

    bottleneck ; 병목현상  (0) 2010.11.04
    sms  (0) 2010.07.13
    Refactoring - Martin P.  (0) 2010.04.26
    Network  (0) 2010.03.24
    MMC/MNC 란?  (0) 2010.02.10
    Posted by jazzlife
    ,

    Android Flow Diagram

    old/Basic 2010. 7. 6. 14:59
     
    Android Anatomy
    Linux Kernel
    • Android는 Linux Kernel을 기반으로 하고 있다.  왜 Linux System이 아닌 Kernel인가?
      • 어찌보면 당연하다. Mobile Device 상에서 full linux 필요없다.  하지만 Android를 넷북이나 UMPC 등으로 영역을 확장한다면 좀 다른 얘기가 될지도 모른다
      • Android is not Linux
        • Android는 Linux Kernel을 기반으로 하는 Mobile Platform이라고 정의하길 선호한다.
      • Native windowing system, glibc support(gnu c library), 표준 linux utilities 등을 포함하지 않고 있다.
        • 일종의 file system 및 하드웨어를 제어하기 위한 드라이버 등, 최소한의 Linux를 채용하고 있다고 볼 수 있다.
        • Android는 Linux Kernel의 안정적인 System 운영 측면을 가져온 것이다.  Linux의 지속적인 업데이트 또한 장점이 되었을 것이다.
        •       


      • Linux 2.6.24를 기반으로 하였으나 최근 발표된 Android 1.5에서는 Linux 2.6.29로 업그레이드 됨
      • Kernel enhancements를 통해 Android를 지원
        • Alarm / Ashmen(Android shared memory) / Binder / Power Management / Low Memory Killer / Kernel Debugger / Logger
      • Why Linux kernel?
        • Great memory and process management
        • Permissions-based security model
        • Proven driver model
        • Support for shared libraries
        • It's already open source
      • Application과 Service는 별개의 process에서 동작을 하지만 상호 communicate 하거나 data를 공유할 필요가 있다.  이는 IPC (Inter Process Communication)를 통해 지원 : Binder
        • High performance through shared memory
        • Per-process thread pool for processing requests
        • Reference counting, and mapping of object reference across processes
        • Synchronous calls between processes
        • AIDL(Android Interface Definition Language)
      • PM (Power Management) Solution
        • 기본적으로 Linux Power Management를 기반으로 구성 (on top of it)
        • More aggressive power management policy - 결국 좀 더 타이트한 policy를 통해 pm을 한다는 내용
        • Components make requests to keep the power on throught "wake locks"
        • Support different types of wake locks
        • Android.os.PowerManager - use wake locks carefully!

    Native Libraries
    • Bionic Libc
      •  What is - 일종의 c library로 android에서는 다음과 같은 이유로 standard c lib가 아닌 bionic libc를 쓰기로 함
        • Bionic은 custom libc implementation, optimized for embedded use
        • License 문제 - standard c lib는 GPL이므로 사용자는 자신의 code를 open 해야 함으로 이로부터 자유롭게 하기 위해
          • BSD License
        • Size - android에서는 will load in each process 해야 함으로, so it needs to be small
          • Small size and fast code paths
        • Fast - mobile device와 같은 한정된 CPU에 최적화되어 빠르다
          • Very fast and small custom pthread implementation
        • 단점 or 장점?
          • Doesn't support certain POSIX features
          • Not compatible with Gnu Libc (glibc)
          • All native code must be compiled against bionic
    • Function Libraries
      • WebKit - 현재까지 알려진 Web 엔진 가운데 가장 괜찮음 : 애플사파리(아이폰포함), Nokia 등이 WebKit 기반 Web 엔진 사용
        • Based on open source WebKit browser
        • Renders pages in full (desktop) view
        • Full CSS, Javascript, DOM, AJAX support
        • Support for single-column and adative view rendering
      • Media Framework
        • Based on PacketVideo OpenCORE platform
        • Supports standard video, audio, still-frame formats
        • Support for hardware/software codec plug-ins - 기본 지원외에 format은 plug-in을 통해 또는 hardware accelerator등이 장착된 mobile device에도 plug-in을 사용하여 fully 지원할 수 있다.
      • SQLite
        • Light-weight transactional data store
        • Back end for most platform data storage
    • Native Servers
      • Surface Flinger
        • Provides system-wide surface "composer", handling all surface rendering to frame buffer device
        • Can combine 2D and 3D surfaces and surfaces from multiple applications
        • Surfaces passed as buffers via Binder IPC calls
        • Can use OpenGL ES and 2D hardware accelerator for its compositions
        • Double-buffering using page-flip
      • Audio Flinger
        • Manages all audio output devices
        • Processes multiple audio streams into PCM audio out paths
        • Handles audio routing to various outputs
    • Hardware Abstraction Libraries
      • User space C/C++ library layer
      • Defines the interface that Android requires hardware "drivers" to implement
      • Separates the Android platform logic from the hardware interface
      • Why do we need a user-space HAL? - HAL 영역이 왜 필요한가 : 당연 - Linux에서 kernel driver가 존재할 텐데 왜 굳이 Android용 HAL을 제공하는가에 대한 문제
        • Not all components have standardized kernel driver interface - 현재 제공되는 Linux system 상에서 모든 component의 driver interface에 대한 표준화가 되어있는 것은 아니다
        • Kernel drivers are GPL which exposes any proprietary IP - kernel driver는 현재 GPL로 되어 있어 그대로 사용하게 되면 연계 소스코드에 대해 오픈을 해야 한다
        • Android has specific requirements for hardware drivers

    Android Runtime
    • Dalvik Virtual Machine
      • 사용자에게 Java를 이용해 app을 작성하게 하고 이러한 Java platform 기반 app을 모바일 device상에서 동작하게 하기 위한 최적의 환경을 제공하기 위해 기존의 Java VM과는 별도로 Google이 제공하는 VM이라고 할 수 있다
      • 일반 VM과는 다음과 같은 다른 특징을 가지고 있다
        • The VM was slimmed down to use less space
        • Dalvik has no Just-in-time compiler
        • The constant pool has been modified to use only 32-bit indexes to simplify the interpreter
        • It uses its own bytecode, not Java bytecode
      • Android's custom clean-room implementation virtual machine
        • Provides application portability and runtime consistency
        • Runs optimized file format (.dex) and Dalvik bytecode
        • Java .class/.jar files converted to .dex at build time
      • Designed for embedded environment
        • Supports multiple virtual machine processes per device
        • Highly CPU-optimized bytecode interpreter
        • Uses runtime memory very efficiently
    • Core Libraries
      • Core APIs for Java language provide a powerful, yet simple and familiar development platform
      • Data structures, Utilities, File access, Network Access, Graphics, …

    Application Framework
    • Core Platform Services
      • Services that are essential to the Android platform
      • Behind the scenes - applications typically don’t access them directly
      • Activity Manager, Package Manager, Window Manager, Resource Manager, Content Providers, View System
    • Hardware Services
      • Provide access to lower-level hardware APIs
      • Typically accessed through local Manager object
        • LocationManager lm = (LocationManager) Context.getSystemService(Context.LOCATION_SERVICE);
      • Telephony Service, Location Service, Bluetooth Service, WiFi Service, USB Service, Sensor Service

    Android Physiology

    Start-up Walkthrough

    • Runtime Walkthrough
      • It all starts with init… - similar to most Linux-based systems at startup, the bootloader loads the Linux kernel and starts the init process.
      • Init starts Linux daemons, including:
        • USB Daemon (usbd) to manage USB connections
        • Android Debug Bridge (adbd) to manage ADB connections
        • Debugger Daemon (debuggerd) to manage debug processes requests (dump memory, etc.)
        • Radio Interface Layer Daemon (rild) to manage communication with the radio
      • Init process starts the zygote process:
        • A nascent process which initializes a Dalvik VM instance
        • Loads classes and listens on socket for requests to spawn VMs
        • Forks on request to create VM instances for managed processes
        • Copy-on-write to maximize re-use and minimize footprint
      • Init starts runtime process:
        • Initializes Service Manager - the context manager for Binder that handles service registration and lookup
        • Registers Service Manager as default context manager for Binder services
      • Runtime process sends request for Zygote to start System Service
        • Zygote forks a new VM instance for the System Service process and starts the service
        • System Service starts the native system servers, including:
          • Surface Flinger, Audio Flinger
      • Native system servers register with Service Manager as IPC service targets:
      • System Service starts the Android managed services:
      • Android managed Services register with Service Manager:
      • After system server loads all services, the system is ready..
      • Each subsequent application is launched in it's own process

    Layer Interaction
    • There are 3 main flavors of Android layer cake:
      • App -> Runtime Service -> lib
      • App -> Runtime Service -> Native Service -> lib
      • App -> Runtime Service -> Native Daemon -> lib
    • App -> Runtime Service -> lib
    • App -> Runtime Service -> Native Service -> lib
    • App -> Runtime Service -> Native Daemon -> lib

    'old > Basic' 카테고리의 다른 글

    안드로이드 AIDL 문법(Android AIDL Syntax)  (0) 2010.09.07
    JNI  (0) 2010.07.06
    Android Bitmap Object Resizing Tip  (0) 2010.07.06
    Handler  (0) 2010.07.06
    aidl  (0) 2010.07.06
    Posted by jazzlife
    ,

    JNI

    old/Basic 2010. 7. 6. 14:58
    이글은, 구글 안드로이드 상의 Java 애플리케이션에서 native c/c++ 모듈을 Call 할 수 있는 가에
    대한 것이다. 결론적으로 말하면 쉽지 않을 것 같지만 불가능 하지는 않을 듯 하다.
    직접 JNI를 통해 결과를 검증해 보지는 않았지만, 대략적인 방법들과 문제점들을 정리해 보고자
    한다.
     
     
    1. JNI란 무엇인가? - JNI example 중심으로
     
    This section presents the ReadFile example program. This example shows how you can use
    the Java Native Interface (JNI) to invoke a native method that makes C function calls to map a
    file into memory.

    About the Example

    You can call code written in any programming language from a program written in the Java
    language by declaring a native Java method, loading the library that contains the native code,
    and then calling the native method. The ReadFile source code below does exactly this.
    However, successfully running the program requires a few additional steps beyond compiling
    the Java language source file. After you compile, but before you run the example, you have to
    generate a header file. The native code implements the function defintions contained in the
    generated header file and implements the business logic as well. The following sections walk
    through all the steps.
    import java.util.*;
    class ReadFile {
     //Native method declaration
       native byte[] loadFile(String name);
     //Load the library
       static {
         System.loadLibrary("nativelib");
       }
     
       public static void main(String args[]) {
          byte buf[];
     //Create class instance
          ReadFile mappedFile=new ReadFile();
     //Call native method to load ReadFile.java
          buf=mappedFile.loadFile("ReadFile.java");
     //Print contents of ReadFile.java
          for(int i=0;i<buf.length;i++) {
              System.out.print((char)buf[i]);
          }
       }
    }
    Native Method Declaration 

    The native declaration provides the bridge to run the native function in the Java virtual machine.
    In this example, the loadFile function maps onto a C function called Java_ReadFile_loadFile.
    The function implementation accepts a String that represents a file name and returns the
    contents of that file in the byte array.
    native byte[] loadFile(String name); Load the Library
    The library containing the native code implementation is loaded by a call to System.loadLibrary().
    Placing this call in a static initializer ensures this library is only loaded once per class.
    The library can be loaded outside of the static block if your application requires it. You might
    need to configure your environment so the loadLibrary method can find your native code library.
    static {
         System.loadLibrary("nativelib");
    }
    Compile the Program
     
    To compile the program, just run the javac compiler command as you normally would:
    javac ReadFile.java
    Next, you need to generate a header file with the native method declaration and implement the
    native method to call the C functions for loading and reading a file.

    Generate the Header File 

    To generate a a header file, run the javah command on the ReadFile class. In this example,
    the generated header file is named ReadFile.h. It provides a method signature that you have
    to use when you implement the loadfile native function.
    javah -jni ReadFile
    Note: When running javah on your own classes, be sure to use the fully-qualified class name.
    Method Signature 

    The ReadFile.h header file defines the interface to map the Java language method to the native
    C function. It uses a method signature to map the arguments and return value of the Java
    language mappedfile.loadFile method to the loadFile native method in the nativelib library.
    Here is the loadFile native method mapping (method signature):
    /* * Class: ReadFile * Method: loadFile * Signature: (Ljava/lang/String;)[B */
    JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile (JNIEnv *, jobject, jstring);
    The method signature parameters function as follows:
    JNIEnv *: A pointer to the JNI environment. This pointer is a handle to the current thread
    in the Java virtual machine, and contains mapping and other hosuekeeping information.
    jobject: A reference to the method that called this native code. If the calling method is
    static, this parameter would be type jclass instead of jobject.
    jstring: The parameter supplied to the native method. In this example, it is the name of
    the file to be read.
     
    Implement the Native Method
     
    In this native C source file, the loadFile definition is a copy and paste of the C declaration
    contained in ReadFile.h. The definition is followed by the native method implementation.
    JNI provides a mapping for both C and C++ by default.
    #include <jni.h>
    #include <sys/types.h>
    #include <sys/
    ipc
    .h>
    #include <sys/shm.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
     
    JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile
      (JNIEnv * env, jobject jobj, jstring name) {
        caddr_t m;
        jbyteArray jb;
        jboolean iscopy;
        struct stat finfo;
        const char *mfile = (*env)->GetStringUTFChars(
                    env, name, &iscopy);
        int fd = open(mfile, O_RDONLY);
        if (fd == -1) {
          printf("Could not open %sn", mfile);
        }
        lstat(mfile, &finfo);
        m = mmap((caddr_t) 0, finfo.st_size,
                    PROT_READ, MAP_PRIVATE, fd, 0);
        if (m == (caddr_t)-1) {
          printf("Could not mmap %sn", mfile);
          return(0);
        }
        jb=(*env)->NewByteArray(env, finfo.st_size);
        (*env)->SetByteArrayRegion(env, jb, 0,
     finfo.st_size, (jbyte *)m);
        close(fd);
        (*env)->ReleaseStringUTFChars(env, name, mfile);
        return (jb);
    }
     
    You can approach calling an existing C function instead of implementing one, in one of two ways:
    Map the name generated by JNI to the existing C function name. The Language Issues
    section shows how to map between Xbase database functions and Java language code
    Use the shared stubs code available from the JNI page on the java.sun.com web site.

    Compile the Dynamic or Shared Object Library 

    The library needs to be compiled as a dynamic or shared object library so it can be loaded at
    runtime. Static or archive libraries are compiled into an executable and cannot be loaded at
    runtime. The shared object or dynamic library for the loadFile example is compiled as follows:
    Gnu C/Linux:
    gcc  -o libnativelib.so -shared -Wl,-soname,libnative.so  
         -I/export/home/jdk1.2/include
         -I/export/home/jdk1.2/include/linux nativelib.c  
         -static -lc
    Gnu C++/Linux with Xbase
    g++ -o libdbmaplib.so -shared -Wl,-soname,libdbmap.so  
        -I/export/home/jdk1.2/include
        -I/export/home/jdk1.2/include/linux
        dbmaplib.cc -static -lc -lxbase

    Win32/WinNT/Win2000
    cl -Ic:/jdk1.2/include
       -Ic:/jdk1.2/include/win32
       -LD nativelib.c -Felibnative.dll

    Run the Example
     
    To run the example, the Java virtual machine needs to be able to find the native library. To do this,
    set the library path to the current directory as follows:

    Unix or Linux: LD_LIBRARY_PATH=`pwd` export LD_LIBRARY_PATH
    Windows NT/2000/95: set PATH=%path%;.

    With the library path properly specified for your platform, invoke the program as you normally would
    with the interpreter command:
     java ReadFile
     
     
    2. 구글 안드로이드 상에서 JNI 지원 API

    아래의 두가지 함수에 대한 안드로이드 상에서의 특별한 제약이 없다면 JNI 을 지원하기 위한 최소한의
    조건은 만족된 듯하다
    The core functional component is the use of the 'native' keyword and the bindings to the
    java.lang.System.loadLibary() API, which, does seem to be documented within the android reference:
     
    java.lang.System
    java.lang
    public final class
    java.lang.System
    java.lang.Object  
           java.lang.System

    Class System provides a standard place for programs to find system related information.
    All System API is static.
    static  void  load(String pathName) : Loads the specified file as a dynamic library.
    static  void  loadLibrary(String libName) : Loads and links the library specified by the argument.

    3. Dynamic & Shard Object Library 만들기
     
    the question here is how to build a native .so (shared library), but we can refer to the JNI example
    above for instructions. we have also been informed, through this list that you can build native code
    on the device, but without UI bindings:
     
    이 부분 중, 가장 어렵게 생각되는 부분은 Cross Compiler를 통해 shard object library를 만들 수 있느냐 일듯.
    현재 안드로이드의 /system/lib 아래에는 안드로이드 Library들이 .so 형태로 존재함.

    'old > Basic' 카테고리의 다른 글

    안드로이드 AIDL 문법(Android AIDL Syntax)  (0) 2010.09.07
    Android Flow Diagram  (0) 2010.07.06
    Android Bitmap Object Resizing Tip  (0) 2010.07.06
    Handler  (0) 2010.07.06
    aidl  (0) 2010.07.06
    Posted by jazzlife
    ,