2008/02/27 21:09

MS-SQL (HAVING, TOP)

HAVING 구문
그룹 또는 집계에 대한 검색 조건을 지정합니다.


USE Pubs
SELECT MONTH(ord_date) ,SUM(qty) FROM YEAR(ord_date) = 1993 HAVING SUM(qty) > 20 ORDER BY SUM(qty) DESC

예를 들어, Pubs 데이터베이스 sales 테이블에서 1993년도 월(ord_date)별 주문량(qty)의 합을 출력하며 주문량의 합이 20 이하인 경우는 제외 합니다.

집계함수가 포함된 건만 사용, SELECT에 나온 함수만 사용해야 함.


SELECT pub_id,AVG(price) FROM titles GROUP BY pub_id HAVING AVG(price) >= 15 ORDER BY AVG(price) DESC

Pubs 데이터베이스 titles 테이블에서 pub_id별로 가격이 15달러 이상인 책의 평균 값을 출력합니다.
AVG()는 평균을 표시.


SELECT pub_id,AVG(YEAR(GETDATE()) - YEAR(hire_date)) FROM employee GROUP BY pub_id HAVING AVG(YEAR(GETDATE()) - YEAR(hire_date)) >= 16
pubs 데이터베이스 employee 테이블에서 pub_id별로 평균 근무 년수가 16년 이상인 경우만 출력합니다.
GETDATE()는 시스템 상의 현재 날짜 표시.



TOP 구문

TOP 절은 결과 집합에 반환되는 행 수를 제한 합니다.

※ 조건에 대한 제한이 아닙니다. 갯수에 제한 입니다^^;; (조건절 제한은 아시죠?)

TOP n [PERCENT]
SELECT [ ALL | DISTINCT ]
[ { TOP integer | TOP integer PERCENT } [ WITH TIES ] ]
< select_list >
[ INTO new_table ]


SELECT TOP 10 * FROM titles

pubs 데이터베이스 titles 테이블에서 상위 10개만 출력합니다.

SELECT TOP 5 WITH TIES * FROM titles ORDER BY ytd_sales DESC

titles 테이블에서 연간 판매량(ytd_sales) 상위 5순위 까지만 출력합니다.

※ 실제 쿼리를 날려보시면 아시겠지만 총 8개의 레코드를 출력합니다. 이유는 WITH TIES때문인데 이 구문이 들어가면 연간 판매량이 같은값도 같이 출력하기 때문입니다. 실제로 승률 또는 전적을 계산할때 타이를 이루는 선수는 같은 랭킹에 랭크 되어야 올바른 쿼리라 할수 있습니다.


SELECT  TOP 1 title, type, price FROM titles WHERE pub_id = '0877' ORDER BY price DESC

pubs 데이터베이스 titles테이블에 출판사ID(pub_id)0877에서 출판된 책 중에서 가장 비싼 책(이름,종류,가격)을 출력합니다.


SELECT TOP 1 title, type, price FROM titles WHERE title LIKE '%computer%' ORDER BY price DESC
pubs 데이터 베이스 titles 테이블에서 책 제목에 computer라는 단어가 포함된 책들 중에서 가장 비싼 책(이름, 종류, 가격)을 출력합니다.


SELECT TOP 1 WITH TIES * FROM employee WHERE MONTH(hire_date) = 03 ORDER BY hire_date

pubs 데이터베이스 employee 테이블에서 입사월이 3월인 사원중에서 입사 년도가 가장 빠른 사원 들을 출력합니다.
출처 MS-SQL (HAVING, TOP)|작성자 소심비형

http://blog.naver.com/ngmaster/120038799517

Trackback 0 Comment 0
2008/02/21 18:43

실시간 로그 모니터링

- 실시간 로그 모니터링
[root localhost log]# tail -f 로그파일



- 로그파일 종류

1. 콘솔 로그
/dev/console
콘솔에 뿌려지는 로그

2. 시스템 로그
/var/log/messages
리눅스 커널로그 및 주된 로그

3. TCPD로그
/var/log/secure
inetd에 의한 로그

4. 메일 로그
/var/log/maillog
sendmail에 의한 로그

5. 크론 로그
/var/log/cron
crond에 의한 로그

6. 부팅 로그
/var/log/boot.log
시스템 부팅시의 로그

7. FTP로그
/var/log/xferlog
FTP로그

8. 웹로그
/usr/local/apache/logs/access_log
아파치 로그

9. 네임서버 로그
/var/log/named.log
네임서버(DNS) 로그
Trackback 0 Comment 0
2008/02/13 16:22

JAVA - 문자열중에 한글체크하기 정말 쉬워요. - getType

Character라는 클래스에
public static int getType(char ch)
getType이라는 메소드가 문자값을 받아 character category값을 리턴해줍니다.
 
  String str = "dasjfl1ie ^&*으샤으샤 ㅁㄴ";
  for(int i=0;i     if(Character.getType(str.charAt(i)) == 5) System.out.print("이건한글이넹 :: ");
     System.out.println(str.charAt(i));
  }

이런식으로 값을 찍어보면 한글의 경우는 5를 리턴합니다.
5가 리턴되면 무조건 한글이겠져..ㅎㅎㅎ

리턴되는 캐릭터 카테고리값들은 static으로 선언되어 있습니다.
COMBINING_SPACING_MARK, CONNECTOR_PUNCTUATION, CONTROL, CURRENCY_SYMBOL, DASH_PUNCTUATION, DECIMAL_DIGIT_NUMBER, ENCLOSING_MARK, END_PUNCTUATION, FORMAT, LETTER_NUMBER, LINE_SEPARATOR, LOWERCASE_LETTER, MATH_SYMBOL, MODIFIER_LETTER, MODIFIER_SYMBOL, NON_SPACING_MARK, OTHER_LETTER, OTHER_NUMBER, OTHER_PUNCTUATION, OTHER_SYMBOL, PARAGRAPH_SEPARATOR, PRIVATE_USE, SPACE_SEPARATOR, START_PUNCTUATION, SURROGATE, TITLECASE_LETTER, UNASSIGNED, UPPERCASE_LETTER

이값들을 체크해서 입력된 문자가 어떤 문자인지 체크가 가능합니다.
그리고 게시판 리스트의 제목을 보여줄때 한글일경우와 영문을 경우를 체크해서
제목테이블 사이즈 만큼 보여주는것도 가능하겠죠...^^

제가 메인화면에 게시글 리스트들을 보여줄때.. 제목의 길이가 길면
String message = a_data[i][1];
int sublen = 0;
StringBuffer sbuf = new StringBuffer();
for(int j=0;(j         if(Character.getType(message.charAt(j)) == 5) sublen=sublen+2;//한글
         else sublen++;//기타 영문,특수문자,공백
         sbuf.append(message.charAt(j));
}
out.println(sbuf.toString()+"...");


문자열중에 한글의 갯수, 특수문자의 갯수.. 등등 원하는 문자만을 자를수도 있습니다.
Trackback 0 Comment 0
2008/02/13 09:07

Windows 환경에서 TAR, GZIP 으로 데이터 백업하기

Backing up data on a Windows machine using TAR and GZIP

Creating a Full Backup

You can create a simple batch file which calls both the tar and gzip programs in turn to create a compressed backup file, which contains all the data files in your specified directory.

Example1.bat

tar -cv –file=backup.tar d:/data*
gzip -9 < backup.tar > backup.tar.tgz
del backup.tar

Backing up More Than One Directory

You can set-up the batch file to backup multiple directory / folder tree structures. Example2.bat shown below demonstrates how this is achieved. You create the initial backup.tar file for your first directory using the -cv command. Then for every other directory structure, you use the -rv command to append the new directory / folder to the backup.tar file.

Example2.bat

tar -cv –file=backup.tar d:/data*
tar -rv –file=backup.tar d:/websites*
gzip -9 < backup.tar > backup.tar.tgz
del backup.tar

Creating an Incremental Backup

Creating an incremental backup is very easy, you just need to specify a date to the –newer command. Tar will then only include files which have changed since that date. The Example3.bat batch file shown below demonstrates creating an incremental backup for all files in the d:/data directory which have been modified since the 1st of September 2004.

Example3.bat

tar -cv –newer=2004-09-01 –file=incremental.tar d:/data*
gzip -9 < incremental.tar > incremental.tar.tgz
del incremental.tar

Download, References

http://downloads.cgi-interactive.net/tar-gzip.zip
http://www.gnu.org/software/tar/manual/index.html
http://www.gnu.org/software/gzip/manual/gzip.html


Related:

출처 : Tong - 창백한달빛님의 창백한달빛님의 기본통통

Trackback 0 Comment 0
2008/02/13 09:03

윈도우즈용 gzip & tar

▣ gzip for Windows

     http://www.gzip.org/



Tar for Windows

     http://gnuwin32.sourceforge.net/packages/tar.htm

Trackback 0 Comment 0
2008/02/13 08:38

외부 실행프로그램을 실행 및 출력값 받기

1. 첫번째 방법

public int getExecuteCommand(String Command) {

    Process p = null;
 
    try {
        p = Runtime.getRuntime().exec(Command);
        p.waitFor ();
   
        if (p.exitValue () != 0) {
            BufferedReader err = new BufferedReader (new InputStreamReader (p.getErrorStream ()));
            while (err.ready())
                System.out.println ("ERR"+err.readLine ());
            err.close ();

        } else {
            BufferedReader out = new BufferedReader (new InputStreamReader (p.getInputStream()));
            while (out.ready())
                System.out.println ("O K"+ out.readLine ());
            out.close ();

        }

        p.destroy ();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
 
    return 0;
}

 

2. 두번째 방법


String cmd = "실행할 명령어 넣어주세용!";
Process p = null;
String returnData = "";

try {
    p = Runtime.getRuntime().exec(cmd);
    InputStream in = p.getInputStream(); // 혹은 getErrorStream
    int i;
    while ((i=in.read()) != -1) {
 
        System.out.println(i);
        returnData += (char)i;
    }
 
    System.out.println("결과"+returnData);
 
} catch (IOException e) {
    e.printStackTrace();
}

Trackback 0 Comment 0
2008/02/12 08:14

간단한 패스워드 암호화 복호화 클래스

public class EncoderDecoder { public static String encoder(String s, int k){ String dst=""; int i=0; byte key=0; s = s.trim(); byte[] b = s.getBytes(); int[] enc = new int[b.length]; key = (byte)(k % 100); for(i=0; i< b.length; i++){ enc[i] = (int)b[i] - key; } for(i=0; i< b.length; i++){ b[i] = (byte)enc[i]; } dst = new String(b); //System.out.println(dst); return dst; } public static String decoder(String s, int k){ String dst=""; int i=0; byte key=0; s = s.trim(); byte[] b = s.getBytes(); int[] enc = new int[b.length]; key = (byte)(k % 100); for(i=0; i< b.length; i++){ enc[i] = (int)b[i] + key; } key = (byte)(k % 100); for(i=0; i< b.length; i++){ b[i] = (byte)enc[i]; } dst = new String(b); //System.out.println(dst); return dst; } public static void main(String[] args) { String src = "aAzZ 09"; int key = 4; String dst = ""; System.out.println("원본문자열:" + src); dst = EncoderDecoder.encoder(src, key); System.out.println("암호화 문자열:" + dst); dst = EncoderDecoder.decoder(dst, key); System.out.println("복구된 문자열:" + dst); src = "itw1 ill"; key = 6; System.out.println("원본문자열:" + src); dst = EncoderDecoder.encoder(src, key); System.out.println("암호화 문자열:" + dst); dst = EncoderDecoder.decoder(dst, key); System.out.println("복구된 문자열:" + dst); src = "가하 01Az"; key = 6; dst = EncoderDecoder.encoder(src, key); System.out.println(dst); dst = EncoderDecoder.decoder(dst, key); System.out.println(dst);  //1234암호화된 문자열: -./0  dst = EncoderDecoder.decoder("-./0", 4); System.out.println(dst);  } } public String decoder(String s){ int k=4; String dst=""; int i=0; byte key=0; s = s.trim(); byte[] b = s.getBytes(); int[] enc = new int[b.length]; key = (byte)(k % 100); for(i=0; i< b.length; i++){ enc[i] = (int)b[i] + key; } key = (byte)(k % 100); for(i=0; i< b.length; i++){ b[i] = (byte)enc[i]; } dst = new String(b); //System.out.println(dst); return dst; }
Trackback 0 Comment 0
2008/02/01 10:46

HttpServletRequest =\= ServletRequest

ServletRequest

ServletRequest의 멤버메서드 [클라이언트 자체에 대한 정보추출]

Object getAttribute(String name): 주어진 이름을 갖는 속성값을 얻습니다.

Enumeration getAttributeNames(): 이 요청이 갖는 속성들의 이름에 대한 Enumeration 객체를 얻습니다.

void setAttribute(String key, Object o): 주어진 이름의 속성을 설정합니다.

void remvoeAttribute(String key): 주어진 이름의 속성을 제거합니다.

String getProtocol(): "HTTP/1.1" 과 같은 형식으로 프로토콜 및 major/minor 버전을 얻습니다.

String getRemoteAddr(): 요청한 클라이언트의 IP(Internet Protocol) 주소를 얻습니다.

String getRemoteHost(): 요청한 클라이언트의 호스트 이름을 얻습니다.

String getScheme(): http, https, 또는 ftp 등과 같은 요청을 위해 사용된 방법의 이름을 얻습니다.

String getServerName(): 요청을 받은 서버의 이름을 얻습니다.

int getServerPort(): 요청을 받은 포트 번호를 얻습니다.

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

 

ServletRequest의 멤버메서드 [클라이언트가 전송한 정보추출]

String getCharacterEncoding(): 이 요청에 사용된 문자 인코딩을 얻습니다.

int getContentLength(): 이 요청에 포함되어 있는 데이터의 길이를 구하며, 만약 길이를 알 수 없는 경우에는 ?1이 리턴됩니다.

String getContentType(): 요청에 포함되어 있는 내용에 대한 MIME 타입 또는 모를 경우에는 null을 얻습니다.

Enumeration getParameterNames(): 매개변수들의 이름에 대한 Enumeration 객체를 얻습니다.

String getParameter(String name): 주어진 이름의 매개변수가 갖는 값을 얻습니다.

String[] getParameterValues(String name): 주어진 이름으로 전달된 매개변수가 갖는 모든 값을 문자열 배열로 얻습니다. 매개변수가 다중 선택이 가능한 리스트(list) 또는 선택박스(choicebox)의 값이라면, 여러 개의 값이 하나의 이름으로 전달될 수 있습니다.

BufferedReader getReader(): 요청 바디로부터 문자 인코딩에 따라 텍스트를 읽어들이기 위한 BufferedReader 객체를 얻습니다.

ServletInputStream getInputStream(): 이 요청의 바디로부터 바이너리 데이터를 읽어들이기 위해, 한 번에 한 라인씩 읽을 수 있는 ServletInputStream 객체를 얻습니다. 

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

 

 

HttpServletRequest

request 객체의 요청 파라미터

public String getParameter(String name) : 주어진 이름의 매개변수가 갖는 값을 얻습니다. 지정된 이름의 파라미터가 존재하지 않을 경우 null을 반환합니다.

public Enumeration getParameterNames(): 매개변수들의 이름에 대한 Enumeration으로 반환합니다.

public String[] getParameterValues(String name) : 주어진 이름으로 전달된 매개변수가 갖는 모든 값을 문자열 배열로 얻습니다. 매개변수가 다중 선택이 가능한 리스트(list) 또는 선택박스(choicebox)의 값이라면, 여러 개의 값이 하나의 이름으로 전달될 수 있지만 매개변수가 하나의 값을 갖는 경우라면 getParameter(String name)를 사용하는 것이 낫습니다.

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

 

request 객체의 HTTP 헤더

public String getHeader(String headerName) : HTTP 요청헤더에 지정된 headerName의 값을 문자열로 반환합니다. 만약 HTTP 요청헤더에 headerName의 값이 존재하지 않는다면 null을 반환합니다.

public Enumeration getHeaderNames() : HTTP 요청헤더에 포함된 모든 헤더의 이름을 Enumeration으로 반환합니다.

public Enumeration getHeaders (String headerName) : HTTP 요청헤더에 포함된 headerName의 모든 값을 Enumeration으로 반환합니다.

public int getIntHeader (String headerName) : HTTP 요청헤더에 포함된 headerName의 값을 int로 반환합니다. 지정된 headerName의 값을 int로 변환 할 수 없는 경우 NumberFormatException이 발생하고 headerName 헤더가 HTTP 요청헤더에 존재하지 않을 경우에는 –1을 반환합니다.

public long getIDateHeader (String headerName) : HTTP 요청헤더에 포함된 headerName의 값을 millisecond 변환하여 long으로 반환합니다. 지정된 headerName의 값을 int로 변환 할 수 없는 경우 IllegalArgumentException이 발생하고 headerName 헤더가 HTTP 요청헤더에 존재하지 않을 경우에는 –1을 반환합니다.

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

 

request객체의 세선 데이터

public HttpSession getSession() : 요청을 시도한 클라이언트에 지정된 HttpSession 객체를 얻습니다.  이전에 생성된 HttpSession 객체가 없었다면 새로운 세션 객체를 생성합니다. 

public HttpSession getSession(boolean create) : 요청을 시도한 클라이언트에 지정된 HttpSession 객체를 얻습니다. create가 false로 지정된 경우 해당 클라이언트에 대해 생성된 HttpSession 객체가 없는 경우 null을 반환합니다. create가 treu로 지정된 경우 이미 생성된 HttpSession 객체를 반환하고 만약 해당 클라이언트에 생성된 HttpSession 객체가 없는 경우 새로운 세션 객체를 생성하여 리턴합니다.

public String getRequestedSessionId(): 요청을 시도한 클라이언트의 세션 id를 문자열로 반환합니다.

public String isRequestedSessionId() : 요청을 시도한 클라이언트의 세션 id가 유효하면 true 아니면 false를 리턴합니다.

isRequestedSessionIdFromCookie() : 요청을 시도한 클라이언트의 세션 id가 쿠키로 전달된 경우 true 아니면 false를 리턴합니다.

isRequestedSessionIdFromURL() : 요청을 시도한 클라이언트의 세션 id가 URL에 포함된 경우 true 아니면 false를 리턴합니다.

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

 

request 객체의 쿠키

public Cookie[] getCookies() : 클라이언트의 요청에 포함된 쿠키를 Cookie배열로 리턴합니다.

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

 

request 객체의 요청에 사용된 URL/URI

public String getRequestURI() : 요청에 사용된 URL로부터 URI부분을 문자열로 리턴합니다.  

public String getQueryString():요청에 사용된 쿼리 문자열을 문자열로 리턴합니다..

public String getMethod() : 요청에 사용된 요청방식을 문자열로 리턴합니다.

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

Trackback 0 Comment 0
2008/01/30 13:39

TOAD KEYBOARD SHORTCUTS

[Toad 단축키]
F1
Toad 도움말 파일의 SQL Editor 부분이 표시됩니다.
F2
전체 화면 Editor Editor/Results 패널 표시 장치 사이를 전환합니다.
<SHIFT>F2
전체 화면 그리드를 전환합니다.
F3
다음으로 일치하는 것을 찾습니다.
<SHIFT>F3
이전에 일치하는 것을 찾습니다.
F4
팝업 창의 테이블, , 프로시저, 함수, 또는 패키지의 정보를 표시합니다.
검색영역을 설정후 F4를 누르면 되여.
F5
스크립트로 실행합니다.
F6
커서를 Editor Results 패널 사이로 전환합니다.
F7
모든 텍스트를 지웁니다.
F8
이전 SQL 문을 재호출합니다(SQL Statement Recall 창을 불러옵니다).
히스토리 정보 표시
F9
실행문을 표형식으로 실행합니다.
<CTRL>F9
실행(구문 분석) 없이 실행문을 검사합니다.
<SHIFT>F9
커서 위치에서 현재 실행문을 실행합니다.
F10
오른쪽 클릭 메뉴를 표시합니다.
F11
Script 같은 실행(=F5)
F12
편집기 내용을 지정된 외부 편집기로 전달합니다.
<CTRL>A
모든 텍스트를 선택합니다.
<CTRL>C
복사
<CTRL>D
프로시저 인수를 표시합니다.
<CTRL>E
현재 실행문에서 Explain Plan 실행합니다.
<CTRL>F
텍스트를 찾습니다(Find Text 창을 불러옵니다).
<CTRL>G
라인으로 이동합니다(Goto Line 창을 불러옵니다).
<CTRL>L
텍스트를 소문자로 변환합니다.
<CTRL>M
Make Code Statement
<CTRL>N
이름이 지정된 SQL 문을 재호출합니다(SQL Statement Recall 창을 불러옵니다).
<CTRL>O
텍스트 파일을 엽니다.
<CTRL>P
Strip Code Statement
<CTRL>R
검색 바꾸기(Find and Replace Text 창을 불러옵니다)
<CTRL>S
파일을 저장합니다.
<SHIFT><CTRL>S
파일을 다른 이름으로 저장합니다.
<CTRL>T
드롭다운을 표시합니다.
<CTRL>U
텍스트를 대문자로 변환합니다.
<CTRL>V
붙여넣기
<CTRL>X
잘라내기
<SHIFT><CTRL>Z
마지막으로 취소한 작업을 재실행합니다.
<ALT><UP>
이전 실행문을 표시합니다.
<ALT><DOWN>
다음 실행문을 표시합니다(<ALT><UP> 사용한 사용)
<ALT><PgUp>
이전 탭으로 이동
<ALT><PgDn>
다음 탭으로 이동
<CTRL><ALT><PgUp>
이전 결과 패널 탭으로 이동
<CTRL><ALT><PgDn>
다음 결과 패널 탭으로 이동
<CTRL><HOME>
데이터 그리드에서는 위의 레코드셋으로 이동하며, 결과 그리드에서는 커서가 위치한 행의 번째 열로 이동하고, 편집기에서는 텍스트의 번째 열과 번째 행으로 이동합니다.
<CTRL><END>
데이터 그리드에서는 레코드셋의 끝으로 이동하며, 편집기에서는 텍스트의 마지막 열과 마지막 행으로 이동합니다. 단원의 "주의" 참조하십시오.
<CTRL><SPACE>
코드 완성 템플릿 활성화합니다.
<CTRL><TAB>
MDI Child 창의 콜렉션을 순환합니다.
<CTRL><ENTER>
커서 이치에서 현재 SQL 문을 실행합니다.
<CTRL>. (마침표)
테이블 이름을 자동으로 완성합니다.

http://blog.empas.com/p14406/22368540
Trackback 0 Comment 0
2008/01/28 18:21

JNI ( JAVA Native Interface ) 사용하기

Java Native Interface
JNI는 native method를 이용해서 C/C++의 code를 Java에서 이용할수 있는 방법이다.
native 메소드를 정의해서, 사용하는 방법에 대해 소개를 하겠습니다.

1. Example Java Source

C/C++의 code를 자바에서 불러 사용하려면, native method를 정의해야 하는데, 아래 코드와 같이
method body를 갖지않는 method를 native keyword를 통해 정의한다.
이것은 method의 body가 C/C++ code의 dll(Unix에서는 so) 파일로 되어 있다는 의미이다.
그래서 runtime에는 이 dll 파일을 메모리에 loading을 해야만 method를 실행할수가 있는데,
dll 파일을 loading하는 library는 System class의 loadLibrary() 메소드이다.
classpath경로에서 파라미터의 파일을 메모리에 loading을 하죠. 

public class Hello {

    public static native void print();

    static {
        System.loadLibrary("hello");
    }

    public static void main(String args[]) {
      Hello.print();
    }
}

compile
prompt>javac Hello.java

compile된 class를 실행하면 당연히 에러가 발생되겠죠. 다음과 같이.
prompt>java Hello
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.libr
ary.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1312)
at java.lang.Runtime.loadLibrary0(Runtime.java:749)
at java.lang.System.loadLibrary(System.java:820)
at Hello.(Hello.java:6)

2. C/C++의 Header file 생성

native method를 C/C++로 구현 하기 위해서는 Java method 선언을 C/C++의 method선언으로
mapping시켜주어야 겠죠.
이것은 javah 라는  명령어를 이용합니다.
그래서, 다음과 같은 명령어로 C/C++의 Header 파일을 생성합니다.

prompt>javah -jni -classpath . -o Hello.h Hello

//생성된 header file : Hello.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class Hello */

#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     Hello
* Method:    print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Hello_print
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

3. C code 생성을 위한 C/C++ compiler install


생성된 header file에 정의된 JNIEXPORT void JNICALL Java_Hello_print(JNIEnv *, jclass); 메소드를
구현하기 위해 Borland C++ Compiler5.5 를 다운 받아 설치한다.


http://www.borland.com/downloads/
설치방법은 인스톨 파일을 실행하면, 설치 디렉토리에 readme file이 있는데, bcc32.cfg, ilink32.cfg 파일을
readme 파일의 내용과 같이 만들어 bin dir에 저장하면 끝난다.

4. C source code

Hello.h 파일에 선언된 메소드를 다음과 같이 구현한다.

//hello.cpp file

#include "Hello.h"

JNIEXPORT void JNICALL Java_Hello_print
(JNIEnv *, jclass)
{
    printf("Hello World");
}

5. compile and dll file 생성

다음과 같은 명령어로 compile해서 hello.dll 파일을 생성한다.

prompt>bcc32 -c -Id:\java\jdk1.3\include -Id:\java\jdk1.3\include\win32 hello.cpp

prompt>bcc32 -tWD hello.obj

6. 실행

hello.dll 파일이 현재 디렉토리에 만들어 졌기 때문에, System.loadLibrary()로 메모리에 loading할수 있고,
print() 라는 native method가 실행될수 있겠죠.

prompt>java Hello
Hello World

2001.06.20 written by Jeon HongSeong

출처 : Tong - 엘레나나무님의 JAVA통

Trackback 0 Comment 0