'language > JAVA' 카테고리의 다른 글
& 0xFF를 사용한 unsigned byte 및 int 비교 방법 (0) | 2010.07.21 |
---|---|
JAVA Native Method (JNI) (1) | 2009.07.01 |
JNI (Java Native Interface) 란 ? (0) | 2009.06.30 |
& 0xFF를 사용한 unsigned byte 및 int 비교 방법 (0) | 2010.07.21 |
---|---|
JAVA Native Method (JNI) (1) | 2009.07.01 |
JNI (Java Native Interface) 란 ? (0) | 2009.06.30 |
11111111 11111111 11111111 10001110 (-114)
00000000 00000000 00000000 11111111 (0xFF)
------------------------------------- 20150831 추가
public class T
{
public static void main(String[] args) throws Exception
{
byte[] b = { (byte)0x34, (byte)0x32, (byte)0x31, (byte)0x8E, (byte)0xF0 };
System.out.println( "i:\t b[i]\t 0xff&b[i]\t toHex(0xff&b[i])" );
for( int i=0; i<=4; i++ )
{
System.out.println(i + ":\t" + b[i] + "\t" + (0xFF&b[i]) + "\t" + Integer.toHexString(0xFF&b[i]));
}
}
}
========================================
C:\>java T
i: b[i] 0xff&b[i] toHex(0xff&b[i])
0: 52 52 34
1: 50 50 32
2: 49 49 31
3: -114 142 8e
4: -16 240 f0
========================================
1. byte & int & bit
1 byte = 8bit : -128 ~ 127, -2^(8-1) ~ 2^(8-1)-1 : 2^8개
1 int = 4 byte = 32bit : -2,147,483,648 ~ 2,147,483,647, -2^(32-1) ~ 2^(32-1)-1 : 2^32개
byte: 00000000
int: 00000000 00000000 00000000 00000000
0x34 = 00000000 00000000 00000000 00110100
(byte)0x34 = 00110100
0x32 = 00000000 00000000 00000000 00110010
(byte)0x32 = 00110010
...
0x8E = 00000000 00000000 00000000 10001110
(byte)0x8E = 10001110 (NOTE: sign bit is 1)
0xF0 = 00000000 00000000 00000000 11110000
(byte)0xF0 = 11110000 (NOTE: sign bit is 1)
2. (byte)0xF0 = 11110000 인데, 가장 좌측의 sign bit가 1이므로, 이는 음수를 뜻합니다.
byte형에 적재된 11110000의 "2의보수"는 00010000 입니다.
11110000
+ 00010000
------------
1 00000000 (마치, 10진수 3의 "10의보수"는 7 이듯...)
00010000 는 2^4 = 16 이므로, 결국 (byte)0xF0 = 11110000 는 -16으로 나타나게 됩니다.
3. 0xFF & b[i]
ex) 0xFF & (byte)0xF0
0xFF = 00000000 00000000 00000000 11111111 { = 32-bit = Integer }
& 11110000 { = (byte)0xF0 = -16 }
------------------------------------
00000000 00000000 00000000 11110000 = 0xF0 = 240 { = 32-bit = Integer }
NOTE: byte로 타입 캐스팅을 해서 출력하면 이상한 값이 들어가는 것처럼 보이는 이유는 byte도 int의 경우처럼 맨 앞의 비트를 sign bit 으로 사용하기 때문입니다. 8bit로 표현되는 0xFF 이하의 수치(0~255)에 한해서 (byte)형으로 casting하게 되면 하여 집어넣을 경우 & 0xFF 연산을 해 주게되면 32-bit 크기(int)로 unsigned byte의 값을 얻을 수 있습니다. (참고: 자바에는 primitive type 으로 unsigned 형이 없습니다.)
=========================================================================================================
자바에서 "int"형은 4byte 로 표현됩니다. 1byte는 8bit 이니 int형은 총 32 bit 로 표현됩니다.
예) int형 1의 bit 표현은 결국 다음과 같습니다.
00000000 00000000 00000000 00000001
32bit를 이용하여 표현하니 총 표현할 수 있는 수치의 개수는 2의 32승, 즉 4,294,967,296 개가 될 것입니다.
그러나, 가장 좌측 bit 는 음수표식을 위해 사용되니(sign bit), 0을 포함하여 31bit로 표현될 수 있는 수의 개수는 2의 (32-1)승개가 됩니다. 2의 31승은 21,47,483,648 이니, 양수로 가장 큰 수는 21,47,483,648-1 입니다. 이 수는 4byte 형에서 다음과 같이 표현됩니다.
01111111 11111111 11111111 11111111 = 21,47,483,647
음수는 "2의보수"로 표현되는데, 예를 들면 int형(4byte,32bit) -1은 "2의보수"로 표현되어,
11111111 11111111 11111111 111111111 로 저장(?) 됩니다.
이는 마치 10진법 3의 10의 보수는 7, 즉
3
+ 7
----
10
이듯이,
00000000 00000000 00000000 000000001
+ 11111111 11111111 11111111 111111111
--------------------------------------
1 00000000 00000000 00000000 000000000
이므로, 00000000 00000000 00000000 000000001 의 int형 "2의 보수"는
11111111 11111111 11111111 111111111 인 것이지요.
"2의보수"를 찾는 알고리즘은 통상 NOT연산 후 +1을 취하면 됩니다. 즉,
|-1| 은 1입니다. 1은 이진수로 00000000 00000000 00000000 000000001 입니다.
이것에 대해 먼저 NOT연산후 11111111 11111111 11111111 111111110,
+1 을 취하면 11111111 11111111 11111111 111111111 입니다.
|-21,47,483,647| 은 01111111 11111111 11111111 11111111 인데,
NOT연산을 취하면 10000000 00000000 00000000 00000000 이고,
+1 을 취하면 10000000 00000000 00000000 00000001 입니다.
|-21,47,483,648| 은 10000000 00000000 00000000 00000000 인데,
NOT연산을 취하면 01111111 11111111 11111111 11111111 이고,
+1 을 취하면 10000000 00000000 00000000 00000000 입니다.
이 처럼 가장 좌측 bit 가 1 인 상태에서 2의 보수로 표현될 수 있는 가장 작은 수는 -21,47,483,648 이 됩니다.
long 형은 8 byte, 64 bit로 표현된다는 것 외엔 동일합니다.
결국, long형의 가장 큰 수는 2의 (64-1)승 -1 인, 9,223,372,036,854,775,807 까지
표현 됩니다. 음수로는 -{2의 (64-1)승} 인 -9,223,372,036,854,775,808 까지 표현되겠지요.
추가로 아래 글들을 참고하세요.
-128>>>1 = 2147483584 ???
http://www.javaservice.net/~java/bbs/read.cgi?m=qna&b=javatip&c=r_p&n=998318237
Re: 1>>> 32 가 1인 이유는 ????
http://www.javaservice.net/~java/bbs/read.cgi?m=qna&b=QandA&c=r_p&n=994003831
[자바의 숫자표현] 어디까지 가능할까 !!!
http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=javatip&c=r_p&n=920434490
[출처] 이원영, 192 Re: 자바의 자료형
http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=javatip&c=r_p&n=1018155018
Decompiler jad (0) | 2010.07.22 |
---|---|
JAVA Native Method (JNI) (1) | 2009.07.01 |
JNI (Java Native Interface) 란 ? (0) | 2009.06.30 |
public class HelloWorld {
public static void main(String arg[]) {
System.out.println("Hello, World");
}
}
public class NativeClass {
public native void setString(String s);
public native void setInt(int i);
public native void setData(float f, double d);
...
}
<표 1> JNI에서 사용하는 데이터 타입과 범위 | |||
Java |
C(JNI) |
비트수 |
C/C++(Win32) |
boolean |
jboolean |
8 unsigned |
unsigned char |
byte |
jbyte |
8 |
unsigned char |
char |
jchar |
16 unsigned |
unsigned short |
short |
jshort |
16 |
short |
int |
jint |
32 |
int |
long |
jlong |
64 |
_int64 (비주얼C++) |
float |
jfloat |
32 |
float |
double |
jdouble |
64 |
double |
void |
void |
- |
void |
<표 2> UTF-8 포맷의 문자열 인코딩 방식 | ||
유니코드(16진수) |
인코딩된 바이트 수 |
UTF-8로 인코딩된 비트(2진수) |
0x0001~0x007F |
1 |
0xxxxxxx |
0x0080~0x07FF |
2 |
110xxxxx 10xxxxxx |
0x0000 |
- |
- |
0x0800~0xFFFF |
3 |
1110xxxx 10xxxxxx 10xxxxxx |
<표 3> ‘한’에 대한 코드 | ||
바이트 문자열(KSC5601) |
유니코드 |
UTF-8 |
0xC7 0xD1 |
0xD55C |
0xED 0x95 0x9C |
2바이트 |
16비트 코드 |
3바이트 |
<표 4> 배열을 다루기 위한 JNI의 GetArrayElements 함수 | ||
JNI 함수 |
리턴타입 |
자바 배열 타입 |
GetBooleanArrayElements() |
jboolean * |
boolean[] |
GetByteArrayElements() |
jbyte * |
byte[] |
GetCharArrayElements() |
jchar * |
char[] |
GetShortArrayElements() |
jshort * |
short[] |
GetIntArrayElements() |
jint * |
int[] |
GetLongArrayElements() |
jlong * |
long[] |
GetFloatArrayElements() |
jfloat * |
float[] |
GetDoubleArrayElements() |
jdouble * |
double[] |
<표 5> 배열을 다루기 위한 JNI의 ReleaseArrayElements 함수 | ||
JNI 함수 |
네이티브 배열 타입 |
자바 배열 타입 |
ReleaseBooleanArrayElements() |
jboolean * |
boolean[] |
ReleaseByteArrayElements() |
jbyte * |
byte[] |
ReleaseCharArrayElements() |
jchar * |
char[] |
ReleaseShortArrayElements() |
jshort * |
short[] |
ReleaseIntArrayElements() |
jint * |
int[] |
ReleaseLongArrayElements() |
jlong * |
long[] |
ReleaseFloatArrayElements() |
jfloat * |
float[] |
ReleaseDoubleArrayElements() |
jdouble * |
double[] |
Decompiler jad (0) | 2010.07.22 |
---|---|
& 0xFF를 사용한 unsigned byte 및 int 비교 방법 (0) | 2010.07.21 |
JNI (Java Native Interface) 란 ? (0) | 2009.06.30 |
1. JNI (Java Native Interface) 란 ?
- 자바가 다른 언어로 만들어진 어플리케이션과 상호 작용할 수 있는 인터페이스를 제공한다.
- 자바가상머신(JVM)이 원시 메소드(native method)를 적재(locate)하고 수행(invoke)할 수 있도록 한다
- JNI가 자바가상머신내에 포함됨으로써, 자바가상머신이 호스트 운영체제상의 입출력, 그래픽스, 네트워킹, 그리고 스레드와 같은 기능들을 작동하기 위한 로컬시스템호출(local system calls)을 수행할 수 있도록 한다.
* 쉽게 말해 Java와 다른 언어를 연동하는 솔루션입니다.
[그림1] C로 만들어진 Library와 JAVA를 연결해주는 JNI
2. Why do you need JNI ?
자바 네이티브 메쏘드(Java Native method, 이하 JNI)는 다른 언어로 작성된 코드를 자바에서 호출하도록 만들어진 규약이다. 현재는 C/C++에 대한 호출만을 정확하게 지원한다. 어떻게 보면 JNI는 자바가 만들어진 철학과 정반대되는 것이다.
그러나. Java에도 한계가 있다.
1. 속도 문제가 있는 계산 루틴
> 자바가 Native Code(플랫폼에 종속적인 기계어 코드)에 비해 느리다.
2. 자바에서 하드웨어 제어
3. 자바에서 지원되지 않은 특정 운영체제 서비스
> 자바의 클래스 라이브러리는 방대하고 다양한 서비스를 제공하지만, 특정 플랫폼에서 제공하는 고유의 서비스의 기능을 모두 포함할 수는 없다. 특히, 특수한 목적으로 제작된 하드웨어를 자바에서 제어해야 할 필요가 있다고 한다면, 자바만으로 해결하기는 힘들다.
4. 기존의 프로그램에서 자바가 제공하는 서비스를 이용
> 기존에 작성된 프로그램이나 기존의 시스템(legacy)과의 연계 문제
∴ JNI를 써서 해결해보자.
3. C를 이용한 JNI 예제
VC++을 이용해 C문법으로 작성되어 만들어진 DLL을 로딩하여 Java에서 사용해보겠습니다.
1단계 : Native Method를 선언하는 자바 클래스 작성
2단계 : 1단계에서 작성한 클래스 컴파일
3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성
4단계 : C언어로 Native Method 실제 구현
5단계 : C 코드와 헤더 파일을 컴파일
6단계 : 자바 프로그램 실행
1단계 : Native Method를 선언하는 자바 클래스 작성
Java 소스 파일 : HelloJni_Jsource.java
import java.util.*;
class HelloJniClass {
native void Hello();
static { System.loadLibrary("Hello_DLL"); }
public static void main(String args[]) {
HelloJniClass myJNI=new HelloJniClass();
myJNI.Hello();
}
}
// 아래는 좀 위의 내용 보충 그림
2단계 : 1단계에서 작성한 클래스 컴파일
* 컴파일시에는 일반 java 컴파일때와 마찬가지로 환경변수 셋팅이 되어 있어야 합니다.
-> Path가 JDK의 Javac.exe가 있는 폴더에 설정되어 있어야 합니다.
3단계 : javah를 사용해서 Native Method가 사용할 헤더 파일 생성
HelloJniClass.h을 열어보면
JNIEXPORT void JNICALL Java_HelloJniClass_Hello (JNIEnv *, jobject);
위의 함수를 Implement만 해서 DLL을 만들면 됩니다. (4단계)
4단계 : C언어로 Native Method 실제 구현(1)
1) VC++ 프로젝트 만들기 : Win32용 DLL 프로젝트로 만듭니다.
New - Projects : Win32 Dynamic-Link Library
2) Add Files Projects : HelloJniClass.h 파일 추가
3) Projects Setings(Alt+F7)
- Link탭에 Output file Name : 1단계의 2. 라이브러리 적재시 작성한 DLL파일명(Hello_DLL.dll)
- C/C++탭 Preprocessor 카테고리의 Additional Include directories
JDK의 Include폴더와 Include폴더 밑의 win32폴더
예) C:\Program Files\Java\jdk1.5.0_03\include\,
C:\Program Files\Java\jdk1.5.0_03\include\win32
4. 값의 전달과 리턴
1단계 : Java 소스 파일 StringPass_Jsource.java
* 일반 자바 메쏘드 선언과 동일합니다.
class JNI_Message {
native byte[] Message(String input);
// 라이브러리 적재(Load the library)
static {
System.loadLibrary("Msg_DLL");
}
public static void main(String args[]) {
byte buf[];
// 클래스 인스턴스 생성(Create class instance)
JNI_Message myJNI=new JNI_Message();
// 원시 메소드에 값을 주고 받음
buf = myJNI.Message("Apple");
System.out.print(buf); // 받은값 출력
}
}
2단계 : 컴파일
javac StringPass_Jsource.java
3단계 : header파일 생성
javah JNI_Message
4단계 : method구현 : StringJNIDLLSource.c
#include <stdio.h>
#include <jni.h>
#include <string.h>
#include "JNI_Message.h"
JNIEXPORT jbyteArray JNICALL Java_JNI_1Message_Message (JNIEnv * env, jobject jobj, jstring input)
{
jbyteArray jb;
jboolean iscopy;
char* buf;
static char outputbuf[20];
buf=(*env)->GetStringUTFChars(env, input, &iscopy); // 입력 String 읽어오는 함수
printf ("\nDLL receive Data from JAVA : %s\n",buf); // 입력받은 내용을 출력
strcpy(outputbuf,"Delicious !!\n");
jb=(*env)->NewStringUTF(env, outputbuf); // 출력할 내용의 java버퍼에 output버퍼값을 셋팅
return(jb); // java버퍼 리턴
}
(*env)->함수명 형태로, JAVA의 메쏘드를 C에서 이용할수 있습니다.
* JAVA는 C로 문자열을 넘겨줄때 UTF-8형태를 사용합니다.
* cpp로 컴파일하지 말고 c로 컴파일 한다.
5단계 : 실행
C:\test\C_JNI\Paramerter Pass>java JNI_Message
DLL receive Data from JAVA : Apple
Delicious !!
5. KVM ? KNI ?
KVM은 J2ME의 일부로서 작고 자원이 한정된 기계장치를 위해 설계된 소형 JVM.
JVM에서는 JNI가 KVM의 KNI가 있다.
6. 기타프로그래밍 이슈들
참고 URL :http://www.javastudy.co.kr/docs/jhan/javaadvance/jni.html
언어적 이슈(Language Issues)
메소드 호출(Calling Methods)
필드의 참조(Accessing Fields)
스레드와 동기화(Threads and Synchronization)
메모리 이슈(Memory Issues)
수행(Invocation)
스레드 연결(Attaching Threads)
Decompiler jad (0) | 2010.07.22 |
---|---|
& 0xFF를 사용한 unsigned byte 및 int 비교 방법 (0) | 2010.07.21 |
JAVA Native Method (JNI) (1) | 2009.07.01 |