JNI 함수 - xrath.com 에서 번역됨

목차 | 전의 항목 | 다음의 항목 | Java Native Interface 스펙

## JNI 함수

## 제 4 장

이 장은, JNI 함수의 레퍼런스입니다. 이 장에서는, JNI 의 함수를 모두 채택합니다. 또, JNI 함수 테이블의 배치 그대로 기재되어 있습니다.

「? 해야 한다」(또는 「? 할 필요가 있다」)이라고 하는 표현은, JNI 프로그래머에 대한 제약을 나타내고 있습니다. 예를 들어, 어느 JNI 함수에 대해, 그것이 null 이외의 객체를 접수취등 「없으면 안 된다」라고 설명되고 있는 경우, 프로그래머의 책임에 대해, 그 JNI 함수에 null 를 건네주지 않게 해야 한다고 하는 의미입니다. 거기에 따라, JNI 구현 시에, 그 JNI 함수에 있어서의 null 의 포인터 체크를 실시할 필요가 없어집니다.

이 장의 일부는 Netscape 의 JRI 문서를 개작한 것입니다.

참조 자료에서는, 함수를 용도에 의해 그룹화 하고 있습니다. 참조 섹션은, 다음의 기능 분야로부터 구성되어 있습니다.

- 버젼 정보
- 클래스 조작
- 예외
- 글로벌 참조 및 로컬 참조
- 약글로벌 참조
- 객체 오퍼레이션
- 객체의 필드에의 액세스
- 인스턴스 메소드의 호출
- static 필드에의 액세스
- static 메소드의 호출
- 캐릭터 라인 조작
- 배열 조작
- 네이티브 메소드의 등록
- 모니터 오퍼레이션
- NIO 의 지원
- 리플렉션의 지원
- Java VM 인터페이스

## 인터페이스 함수 테이블

각 함수는, 「JNIEnv」인수를 개입시켜, 고정 오프셋(offset)로부터 액세스 할 수 있습니다. 「JNIEnv」형은, 모든 JNI 함수의 포인터를 포함하는 구조체를 가리키는 포인터입니다. 이것은 다음과 같이 정의됩니다.

    typedef const struct JNINativeInterface *JNIEnv;

VM 는,코드예 4-1 에 나타나고 있도록(듯이), 함수 테이블을 초기화합니다. 최초의 3 엔트리는, 장래의 COM 와의 호환성을 위해서(때문에) 예약되고 있는 것에 주의해 주세요. 게다가 함수 테이블의 초의 부근에 몇개의 추가의 `null` 엔트리를 예약되어 있습니다. 따라서, 예를 들어, 지금부터 나타나는, 클래스 관련의 JNI 연산은, 겉(표)의 마지막은 아니고 FindClass 의 후에 추가할 수가 있습니다.

함수 테이블은, 모든 JNI 인터페이스 포인터의 사이에 공용됩니다.

코드예 4-1

    const struct JNINativeInterface ... = {

        NULL,
        NULL,
        NULL,
        NULL,
        GetVersion,

        DefineClass,
        FindClass,

        FromReflectedMethod,
        FromReflectedField,
        ToReflectedMethod,

        GetSuperclass,
        IsAssignableFrom,

        ToReflectedField,

        Throw,
        ThrowNew,
        ExceptionOccurred,
        ExceptionDescribe,
        ExceptionClear,
        FatalError,

        PushLocalFrame,
        PopLocalFrame,

        NewGlobalRef,
        DeleteGlobalRef,
        DeleteLocalRef,
        IsSameObject,
        NewLocalRef,
        EnsureLocalCapacity,

        AllocObject,
        NewObject,
        NewObjectV,
        NewObjectA,

        GetObjectClass,
        IsInstanceOf,

        GetMethodID,

        CallObjectMethod,
        CallObjectMethodV,
        CallObjectMethodA,
        CallBooleanMethod,
        CallBooleanMethodV,
        CallBooleanMethodA,
        CallByteMethod,
        CallByteMethodV,
        CallByteMethodA,
        CallCharMethod,
        CallCharMethodV,
        CallCharMethodA,
        CallShortMethod,
        CallShortMethodV,
        CallShortMethodA,
        CallIntMethod,
        CallIntMethodV,
        CallIntMethodA,
        CallLongMethod,
        CallLongMethodV,
        CallLongMethodA,
        CallFloatMethod,
        CallFloatMethodV,
        CallFloatMethodA,
        CallDoubleMethod,
        CallDoubleMethodV,
        CallDoubleMethodA,
        CallVoidMethod,
        CallVoidMethodV,
        CallVoidMethodA,

        CallNonvirtualObjectMethod,
        CallNonvirtualObjectMethodV,
        CallNonvirtualObjectMethodA,
        CallNonvirtualBooleanMethod,
        CallNonvirtualBooleanMethodV,
        CallNonvirtualBooleanMethodA,
        CallNonvirtualByteMethod,
        CallNonvirtualByteMethodV,
        CallNonvirtualByteMethodA,
        CallNonvirtualCharMethod,
        CallNonvirtualCharMethodV,
        CallNonvirtualCharMethodA,
        CallNonvirtualShortMethod,
        CallNonvirtualShortMethodV,
        CallNonvirtualShortMethodA,
        CallNonvirtualIntMethod,
        CallNonvirtualIntMethodV,
        CallNonvirtualIntMethodA,
        CallNonvirtualLongMethod,
        CallNonvirtualLongMethodV,
        CallNonvirtualLongMethodA,
        CallNonvirtualFloatMethod,
        CallNonvirtualFloatMethodV,
        CallNonvirtualFloatMethodA,
        CallNonvirtualDoubleMethod,
        CallNonvirtualDoubleMethodV,
        CallNonvirtualDoubleMethodA,
        CallNonvirtualVoidMethod,
        CallNonvirtualVoidMethodV,
        CallNonvirtualVoidMethodA,

        GetFieldID,

        GetObjectField,
        GetBooleanField,
        GetByteField,
        GetCharField,
        GetShortField,
        GetIntField,
        GetLongField,
        GetFloatField,
        GetDoubleField,
        SetObjectField,
        SetBooleanField,
        SetByteField,
        SetCharField,
        SetShortField,
        SetIntField,
        SetLongField,
        SetFloatField,
        SetDoubleField,

        GetStaticMethodID,

        CallStaticObjectMethod,
        CallStaticObjectMethodV,
        CallStaticObjectMethodA,
        CallStaticBooleanMethod,
        CallStaticBooleanMethodV,
        CallStaticBooleanMethodA,
        CallStaticByteMethod,
        CallStaticByteMethodV,
        CallStaticByteMethodA,
        CallStaticCharMethod,
        CallStaticCharMethodV,
        CallStaticCharMethodA,
        CallStaticShortMethod,
        CallStaticShortMethodV,
        CallStaticShortMethodA,
        CallStaticIntMethod,
        CallStaticIntMethodV,
        CallStaticIntMethodA,
        CallStaticLongMethod,
        CallStaticLongMethodV,
        CallStaticLongMethodA,
        CallStaticFloatMethod,
        CallStaticFloatMethodV,
        CallStaticFloatMethodA,
        CallStaticDoubleMethod,
        CallStaticDoubleMethodV,
        CallStaticDoubleMethodA,
        CallStaticVoidMethod,
        CallStaticVoidMethodV,
        CallStaticVoidMethodA,

        GetStaticFieldID,

        GetStaticObjectField,
        GetStaticBooleanField,
        GetStaticByteField,
        GetStaticCharField,
        GetStaticShortField,
        GetStaticIntField,
        GetStaticLongField,
        GetStaticFloatField,
        GetStaticDoubleField,

        SetStaticObjectField,
        SetStaticBooleanField,
        SetStaticByteField,
        SetStaticCharField,
        SetStaticShortField,
        SetStaticIntField,
        SetStaticLongField,
        SetStaticFloatField,
        SetStaticDoubleField,

        NewString,

        GetStringLength,
        GetStringChars,
        ReleaseStringChars,

        NewStringUTF,
        GetStringUTFLength,
        GetStringUTFChars,
        ReleaseStringUTFChars,

        GetArrayLength,

        NewObjectArray,
        GetObjectArrayElement,
        SetObjectArrayElement,

        NewBooleanArray,
        NewByteArray,
        NewCharArray,
        NewShortArray,
        NewIntArray,
        NewLongArray,
        NewFloatArray,
        NewDoubleArray,

        GetBooleanArrayElements,
        GetByteArrayElements,
        GetCharArrayElements,
        GetShortArrayElements,
        GetIntArrayElements,
        GetLongArrayElements,
        GetFloatArrayElements,
        GetDoubleArrayElements,

        ReleaseBooleanArrayElements,
        ReleaseByteArrayElements,
        ReleaseCharArrayElements,
        ReleaseShortArrayElements,
        ReleaseIntArrayElements,
        ReleaseLongArrayElements,
        ReleaseFloatArrayElements,
        ReleaseDoubleArrayElements,

        GetBooleanArrayRegion,
        GetByteArrayRegion,
        GetCharArrayRegion,
        GetShortArrayRegion,
        GetIntArrayRegion,
        GetLongArrayRegion,
        GetFloatArrayRegion,
        GetDoubleArrayRegion,
        SetBooleanArrayRegion,
        SetByteArrayRegion,
        SetCharArrayRegion,
        SetShortArrayRegion,
        SetIntArrayRegion,
        SetLongArrayRegion,
        SetFloatArrayRegion,
        SetDoubleArrayRegion,

        RegisterNatives,
        UnregisterNatives,

        MonitorEnter,
        MonitorExit,

        GetJavaVM,

        GetStringRegion,
        GetStringUTFRegion,

        GetPrimitiveArrayCritical,
        ReleasePrimitiveArrayCritical,

        GetStringCritical,
        ReleaseStringCritical,

        NewWeakGlobalRef,
        DeleteWeakGlobalRef,

        ExceptionCheck,

        NewDirectByteBuffer,
        GetDirectBufferAddress,
        GetDirectBufferCapacity

        GetObjectRefType
    };

## 버젼 정보

### GetVersion

`jint GetVersion(JNIEnv *env);`

네이티브 메소드 인터페이스의 버젼을 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 4.

##### 파라미터:

`env`:JNI 인터페이스 포인터

##### 반환값:

메이저 버젼 번호를 고위의 16 비트로, 마이너 버젼 번호를 하위의 16 비트로 돌려줍니다.

SDK/JRE 1.1 에서는,`GetVersion()` 은 `0x00010001` 를 돌려줍니다.

SDK/JRE 1.2 에서는,`GetVersion()` 는 `0x00010002` 를 돌려줍니다.

SDK/JRE 1.4 에서는,`GetVersion()` 는 `0x00010004` 를 돌려줍니다.

SDK/JRE 1.6 에서는,`GetVersion()` 은 `0x00010006` 를 돌려줍니다.

### 정수

##### SDK/JRE 1.2 이후:

>     #define JNI_VERSION_1_1 0x00010001
>     #define JNI_VERSION_1_2 0x00010002

>     /* Error codes */
>     #define JNI_EDETACHED    (-2)              /* thread detached from the VM */
>     #define JNI_EVERSION     (-3)              /* JNI version error

##### SDK/JRE 1.4 이후:

        #define JNI_VERSION_1_4 0x00010004

##### SDK/JRE 1.6 이후:

        #define JNI_VERSION_1_6 0x00010006

## 클래스 조작

### DefineClass

`jclass DefineClass(JNIEnv *env, jobject loader,
const jbyte *buf, jsize bufLen);`

raw 클래스 데이터의 버퍼로부터 클래스를 로드합니다. raw 클래스 데이터를 포함한 버퍼는, DefineClass 호출이 돌아온 후는 VM 에 의해 참조되지 않습니다. 필요에 따라서 파기해도 상관하지 않습니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 5.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`loader`:정의된 클래스에 할당할 수 있는 클래스 로더

`buf`:`. class`파일 데이터를 포함한 버퍼

`bufLen`:버퍼장

##### 반환값:

Java 클래스 객체를 돌려줍니다. 에러가 발생했을 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`ClassFormatError`:클래스 데이터가 유효한 클래스를 지정하지 않았던 경우

`ClassCircularityError`:클래스 또는 인터페이스가, 그 자체의 슈퍼 클래스 또는 슈퍼 인터페이스가 되는 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### FindClass

`jclass FindClass(JNIEnv *env, const char *name);`

이 함수는, 로컬에 정의된 클래스를 로드합니다. 또, 지정된 이름을 가지는 클래스에 대해서 `CLASSPATH` 환경 변수가 지정하는 디렉토리 및 ZIP 파일을 검색합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 6.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`name`:완전 수식 클래스명 ( 「`/`」으로 단락지은 뒤에 클래스명을 붙인 패키지명). 그 이름이 「`[`」(배열 시그니챠 문자)로 시작되어 있는 경우는, 배열 클래스를 돌려줍니다.

##### 반환값:

완전 수식명으로부터 클래스 객체를 돌려줍니다. 클래스가 발견되지 않는 경우는,`NULL` 를 돌려줍니다.

##### 예외:

`ClassFormatError`:클래스 데이터가 유효한 클래스를 지정하지 않았던 경우

`ClassCircularityError`:클래스 또는 인터페이스가, 그 자체의 슈퍼 클래스 또는 슈퍼 인터페이스가 되는 경우

`NoClassDefFoundError`:요구된 클래스 또는 인터페이스에 대한 정의가 발견되지 않았던 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

##### SDK/JRE 1.2 이후:

JDK 1.1 에서는,`FindClass` 는 `CLASSPATH` 내의 로컬 클래스만을 검색했습니다. 검색된 클래스는, 클래스 로더를 가지고 있지 않았습니다.

Java 시큐리티 모델은 확장되어 시스템 클래스 이외의 클래스에 의한 네이티브 메소드의 로드 및 호출이 가능하게 되었습니다. Java 2 플랫폼에서는,`FindClass` 가, 현재의 네이티브 메소드와 관련지을 수 있고 있는 클래스 로더를 검출합니다. native code가 시스템 클래스에 속하는 경우, 클래스 로더는 검출되지 않습니다. 그 이외의 경우에는, 적절한 클래스 로더가 불려 가 이름을 붙일 수 있었던 클래스의 로드 및 링크를 실시합니다.

`FindClass` 가 호출해 인터페이스에 의해 불려 갔을 경우, 현재의 네이티브 메소드 또는 거기에 관련지을 수 있었던 클래스 로더는 존재하지 않습니다. 이 경우,`ClassLoader.getBaseClassLoader` 의 결과가 사용됩니다. 이것은, 가상 머신이 어플리케이션용으로 작성하는 클래스 로더입니다. `java.class.path` 프로퍼티에 리스트 된 클래스를 검색할 수 있습니다.

### GetSuperclass

`jclass GetSuperclass(JNIEnv *env, jclass clazz);`

`clazz` 가 `Object` 클래스 이외의 클래스를 나타내는 경우, 이 함수는,`clazz` 에 의해 지정된 클래스의 슈퍼 클래스를 나타내는 객체를 돌려줍니다.

`clazz` 가 `Object` 클래스를 지정하는 경우, 또는 `clazz` 가 인터페이스를 나타내는 경우는, 이 함수는 `NULL` 를 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 10.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

##### 반환값:

`clazz` 에 의해 나타내지는 클래스의 슈퍼 클래스, 또는 `NULL` 를 돌려줍니다.

### IsAssignableFrom

`jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1,
jclass clazz2);`

`clazz1` 의 객체가 안전하게 `clazz2` 에 캐스트 될지 어떨지를 결정합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 11.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz1`:최초의 클래스 인수

`clazz2`:2 번째의 클래스 인수

##### 반환값:

다음중 한쪽이 진정한 경우에 `JNI_TRUE` 를 돌려줍니다.

- 최초와 2 번째의 클래스 인수가 같은 Java 클래스를 나타내고 있다
- 최초의 클래스가 2 번째의 클래스의 서브 클래스이다
- 최초의 클래스가 그 인터페이스로서 2 번째의 클래스를 가지고 있다

## 예외

### Throw

`jint Throw(JNIEnv *env, jthrowable obj);`

`java.lang.Throwable` 객체가 throw 됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 13.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:`java.lang.Throwable` 객체

##### 반환값:

성공하면(자) 「0」을 돌려주어, 실패하면(자) 0 보다 작은 값을 돌려줍니다.

##### 예외:

`` `java.lang.Throwable` `object` `obj``.`

### ThrowNew

`jint ThrowNew(JNIEnv *env, jclass clazz,
const char *message);`

`message` 에 의해 지정된 메세지를 사용해, 지정된 클래스로부터 예외 객체를 구축해, 그 예외가 throw 되도록(듯이) 합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 14.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:`java.lang.Throwable` 의 서브 클래스

`message`:`java.lang.Throwable` 객체의 구축에 사용하는 메세지

##### 반환값:

성공하면(자) 「0」을 돌려주어, 실패하면(자) 0 보다 작은 값을 돌려줍니다.

##### 예외:

새롭게 구축된`` `java.lang.Throwable``` 객체.

### ExceptionOccurred

`jthrowable ExceptionOccurred(JNIEnv *env);`

예외가 throw 될지 어떨지를 결정합니다. 예외는, native code가 `ExceptionClear()` 을 호출하는지, 또는 Java 코드가 그 예외를 처리할 때까지 throw 된 상태를 계속합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 15.

##### 파라미터:

`env`:JNI 인터페이스 포인터

##### 반환값:

현재 throw 되고 있는 예외 객체를 돌려줍니다. 현재 throw 되고 있는 예외가 없는 경우는,`NULL` 를 돌려줍니다.

### ExceptionDescribe

`void ExceptionDescribe(JNIEnv *env);`

`stderr` 등, 예외 및 스택의 백 트레이스를 시스템 우류 보고 채널에 출력합니다. 이것은, 디버그를 위해서(때문에) 제공되고 있는 편리한 루틴입니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 16.

##### 파라미터:

`env`:JNI 인터페이스 포인터

### ExceptionClear

`void ExceptionClear(JNIEnv *env);`

현재 throw 되고 있는 예외가 있으면 그것을 클리어 합니다. 현재 throw 되고 있는 예외가 없는 경우는, 이 루틴은 영향을 미치지 않습니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 17.

##### 파라미터:

`env`:JNI 인터페이스 포인터

### FatalError

`void FatalError(JNIEnv *env, const char *msg);`

치명적 에러를 발생시킵니다. VM 의 회복은 기대할 수 없습니다. 이 함수는 값을 돌려주지 않습니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 18.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`msg`:에러 메세지

### ExceptionCheck

예외 객체에의 로컬 참조를 작성하지 않고 , 미처리의 예외를 확인하기 위한 편리한 함수를 다음에 나타냅니다.

`jboolean ExceptionCheck(JNIEnv *env);`

> 미처리의 예외가 있는 경우는 `JNI_TRUE` 를, 없는 경우는 `JNI_FALSE` 를 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 228.

##### 도입된 버젼:

SDK/JRE 1.2

## 글로벌 참조 및 로컬 참조

### 글로벌 참조

### NewGlobalRef

`jobject NewGlobalRef(JNIEnv *env, jobject obj);`

`obj` 인수에 의해 참조된 객체의 새로운 글로벌 참조를 작성합니다. `obj` 인수는, 글로벌 참조 또는 로컬 참조의 어디라도 상관하지 않습니다. 글로벌 참조는,`DeleteGlobalRef()` 를 호출하는 것에 의해, 반드시 명시적으로 처리해 둘 필요가 있습니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 21.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:글로벌 참조 또는 로컬 참조

##### 반환값:

글로벌 참조를 돌려줍니다. 시스템이 메모리 부족의 경우는 `NULL` 를 돌려줍니다.

### DeleteGlobalRef

`void DeleteGlobalRef(JNIEnv *env, jobject globalRef);`

`globalRef` 에 의해 나타난 글로벌 참조를 삭제합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 22.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`globalRef`:글로벌 참조

### 로컬 참조

로컬 참조는, 네이티브 메소드의 호출 기간중 유효합니다. 로컬 참조는, 네이티브 메소드가 복귀하면(자) 자동적으로 해제됩니다. 각 로컬 참조는, Java 가상 머신의 자원을 얼마인가 소비합니다. 프로그래머는, 네이티브 메소드가 로컬 참조를 과잉에 할당하지 않게 확인할 필요가 있습니다. 로컬 참조는, 네이티브 메소드가 Java 에 복귀하면(자) 자동적으로 해제됩니다만, 로컬 참조를 과잉에 할당하면(자), 네이티브 메소드의 실행중에 VM 가 메모리를 다 써 버려 버릴 가능성이 있습니다.

### DeleteLocalRef

`void DeleteLocalRef(JNIEnv *env, jobject localRef);`

`localRef` 에 의해 나타난 로컬 참조를 삭제합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 23.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`localRef`:로컬 참조

## 주:

SDK/JRE 1.1 에서는,`DeleteLocalRef` 함수가 준비되어 있기 (위해)때문에, 프로그래머는 수동으로 로컬 참조를 삭제할 수가 있었습니다. 예를 들어, native code가 객체의 잠재적으로 큰 배열을 반복에 의해 처리해, 반복 마다 1 개의 요소를 사용하는 경우, 다음의 반복으로 새로운 로컬 참조가 작성되기 전에, 이제 사용되지 않는 배열 요소에의 로컬 참조를 삭제하는 것은 좋은 방법입니다.

Java 2 SDK/JRE 1.2 이후의 버젼에서는, 로컬 참조의 유효기간의 관리용으로 함수세트가 추가되었습니다. 그 함수는 다음의 4개입니다.

### EnsureLocalCapacity

`jint EnsureLocalCapacity(JNIEnv *env, jint capacity);`

현재의 thread로 최저한 지정된 수의 로컬 참조를 작성할 수 있는 것을 보증합니다. 함수가 정상적으로 실행되었을 경우에는, 0 이 돌려주어집니다. 그 이외의 경우에는, 부의 수가 돌려주어지고 `OutOfMemoryError` 가 throw 됩니다.

네이티브 메소드에 들어가기 전에, VM 는 자동적으로 최저 16 의 로컬 참조의 작성을 보증합니다.

하위 호환성을 위해서(때문에) VM 는, 보증된 용량 이상으로 로컬 참조를 할당합니다. (디버그의 지원로서 VM 가 사용자에 대해, 로컬 참조의 작성수가 너무 많다고 하는 내용의 경고를 발표하는 경우가 있습니다. Java 2 SDK 에서는, 프로그래머는`-verbose:jni` 커멘드행 옵션을 공급해, 이러한 메세지를 유효하게 할 수가 있는) 보증된 용량을 넘어 버려, 더 이상 로컬 참조를 작성할 수 없는 경우, VM 는,`FatalError` 를 호출합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 26.

##### 도입된 버젼:

SDK/JRE 1.2

### PushLocalFrame

`jint PushLocalFrame(JNIEnv *env, jint capacity);`

새로운 로컬 참조 프레임을 작성합니다. 이 프레임에 최저한 지정된 수의 로컬 참조를 작성할 수 있습니다. 정상적으로 실행되었을 경우에는, 0 이 돌려주어집니다. 실패했을 경우에는, 부의 수가 돌려주어져`OutOfMemoryError` 가 throw 됩니다.

전회의 로컬 프레임으로 작성 끝난 로컬 참조는, 현재의 로컬 프레임에서도 여전히 유효합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 19.

##### 도입된 버젼:

SDK/JRE 1.2

### PopLocalFrame

`jobject PopLocalFrame(JNIEnv *env, jobject result);`

현재의 로컬 참조 프레임을 무효로 해, 모든 로컬 참조를 해제합니다. 그리고 지정된 `result` 객체에 대한 전회의 로컬 참조 프레임의 로컬 참조를 돌려줍니다.

전회의 프레임에 참조를 돌려줄 필요가 없는 경우에는,`result` 로서 `null` 를 건네줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 20.

##### 도입된 버젼:

SDK/JRE 1.2

### NewLocalRef

`jobject NewLocalRef(JNIEnv *env, jobject ref);`

`ref` 와 같은 객체를 참조하는 새로운 로컬 참조를 작성합니다. 건네받은 `ref` 는, 글로벌 참조 또는 로컬 참조일 가능성이 있습니다. `ref` 가 `null` 를 참조하고 있는 경우에는,`null` 가 돌려주어집니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 25.

##### 도입된 버젼:

SDK/JRE 1.2

## 약글로벌 참조

약글로벌 참조는, 특별한 종류의 글로벌 참조입니다. 일반적으로의 글로벌 참조와 달리, 약글로벌 참조를 사용하면(자), 부하의 Java 객체를 가베지 컬렉트할 수가 있습니다. 약글로벌 참조는, 글로벌 또는 로컬 참조가 사용되고 있는 상황이라면 어디서에서도 사용할 수 있습니다. 가비지 컬렉터를 실행하면(자), 부하의 객체가 약참조 에 의해서만 참조되고 있는 경우, 그 객체가 해제됩니다. 해제된 객체를 참조하는 약글로벌 참조는, 기능적으로 `null` 와 동등합니다. 프로그래머는,`IsSameObject` 를 사용해 약참조와 `null` 를 비교하는 것으로써, 약글로벌 참조가 해제된 객체를 참조하고 있을지 어떨지 확인할 수 있습니다.

JNI 의 약글로벌 참조는, Java 2 플랫폼 API (`java.lang.ref` 및 그 클래스)의 일부로서 입수 가능한 Java 약참조의 간이판입니다.

해설 (2001년 6월에 추가)

> 가베지 컬렉션은 네이티브 메소드의 실행중에 발생하기 위해(때문에), 약글로벌 참조로 참조되고 있는 객체는 언제라도 해제할 수 있습니다. 약글로벌 참조는, 글로벌 참조가 사용되고 있는 곳(중)이라면 어디에서라도 사용할 수 있습니다만, 그처럼 사용한다고 예고없이 `null` 와 기능적으로 동등하게 되는 경우가 있으므로, 일반적으로는 부적절합니다.

> 「`IsSameObject`」는 약글로벌 참조가 해제된 객체를 참조하고 있을지 어떨지를 판별하는데 사용할 수 있습니다만, 객체가 그 직후에 해제되는 것을 방지하는 것은 아닙니다. 그 때문에, 프로그래머는 이 검사에 근거해, 그 후의 JNI 호출로 약글로벌 참조가 (`null` 참조 이외로) 사용되고 있는지 어떤지를 판별할 수 없습니다.

> 이 상속 제한을 해소하기 위해(때문에), JNI 함수 「`NewLocalRef`」또는 「`NewGlobalRef`」를 사용해 동일한 객체에의 표준 (강하다) 로컬 참조 또는 글로벌 참조를 취득해, 이 강한 참조를 사용해 해당하는 객체에 액세스 하는 것을 추천합니다. 객체가 해제되고 있는 경우, 이 함수는 `null` 를 돌려줍니다. 그 외의 경우, 강한 참조를 돌려줍니다 (강한 참조는 객체가 해제되는 것을 방지합니다). 객체에의 직접 액세스가 불필요하게 되었을 때는, 객체를 해제할 수 있도록(듯이), 새로운 참조를 명시적으로 삭제할 필요가 있습니다.

> 약글로벌 참조는, 다른 종류의 약한 참조 (SoftReference 클래스 또는 WeakReference 클래스의 Java 객체)보다 약한 참조입니다. 특정의 객체에의 약한 글로벌 참조는, 그 객체를 참조하는 SoftReference 객체 또는 WeakReference 객체가 참조를 해제할 때까지, 기능적으로 `null` 와 동등하게는 되지 않습니다.

> 약글로벌 참조는, finalize를 필요로 하는 객체에의 Java 의 내부 참조보다 약한 참조입니다. 약글로벌 참조는, 참조처의 객체의 파이나라이자가 존재하는 경우, 그것이 완료할 때까지,`null` 와 기능적으로 동등하게는 되지 않습니다.

> 약글로벌 참조와 PhantomReference 와의 상호 동작은 미정도리입니다. 특히, Java VM 의 구현은, PhantomReference 의 후에 약글로벌 참조를 처리하는 경우가 있어, PhantomReference 객체에서도 참조되고 있는 객체를 보관 유지하기 위해서 약글로벌 참조를 사용하는 것이 가능한 경우가 있습니다. 약글로벌 참조를 이러한 미정도리의 방법으로 사용하는 것은 피해야 합니다.

### NewWeakGlobalRef

`jweak NewWeakGlobalRef(JNIEnv *env, jobject obj);`

약글로벌 참조를 신규 작성합니다. `obj` 가 `null` 를 참조하고 있는 경우, 또는 VM 가 메모리를 다 써 버려 버렸을 경우는,`null` 가 돌려주어집니다. VM 가 메모리를 다 써 버려 버렸을 경우,`OutOfMemoryError` 가 throw 됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 226.

##### 도입된 버젼:

SDK/JRE 1.2

### DeleteWeakGlobalRef

`void DeleteWeakGlobalRef(JNIEnv *env, jweak obj);`

건네받은 약글로벌 참조에 필요한 VM 자원을 삭제합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 227.

##### 도입된 버젼:

SDK/JRE 1.2

## 객체 오퍼레이션

### AllocObject

`jobject AllocObject(JNIEnv *env, jclass clazz);`

객체용으로서 생성자 을 호출하지 않고 , 새로운 Java 객체를 할당합니다. 객체에 대한 참조를 돌려줍니다.

clazz 인수는 배열 클래스를 참조할 수 없습니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 27.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

##### 반환값:

Java 객체를 돌려줍니다. Java 객체를 구축할 수 없었던 경우는,`NULL` 를 돌려줍니다.

##### 예외:

`InstantiationException`:클래스가 인터페이스 또는 abstract 클래스의 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### NewObject
NewObjectA
NewObjectV

`jobject NewObject(JNIEnv *env, jclass clazz,
jmethodID methodID, ...);`

`jobject NewObjectA(JNIEnv *env, jclass clazz,
jmethodID methodID, jvalue *args);`

`jobject NewObjectV(JNIEnv *env, jclass clazz,
jmethodID methodID, va_list args);`

새로운 Java 객체를 구축합니다. 메소드 ID 는, 호출해야 할 생성자 메소드를 나타내고 있습니다. 이 ID 는, 메소드명으로서 `<init>` 를, 또 반환값의 형태로서 `void` (`V`)를 사용해 `GetMethodID()` 를 호출하는 것에 의해 취득하지 않으면 안됩니다.

`clazz` 인수는 배열 클래스를 참조할 수 없습니다.

##### NewObject

프로그래머는, 생성자 에 건네주는 인수를 모두,`methodID` 인수의 직후에 둡니다. `NewObject()` 는, 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 28.

##### NewObjectA

프로그래머는, 생성자 에 건네주는 인수를 모두,`methodID` 인수의 직후의 `jvalues` 의 `args` 배열내에 둡니다. `NewObjectA()` 는 이 배열내의 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 30.

##### NewObjectV

프로그래머는, 생성자 에 건네주는 인수를 모두,`methodID` 인수의 직후의 `va_list` 형의 `args` 인수내에 둡니다. `NewObjectV()` 는 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 29.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`methodID`:생성자 의 메소드 ID

##### NewObject 에 필요한 추가 파라미터:

생성자 의 인수.

##### NewObjectA 에 필요한 추가 파라미터:

`args`:생성자 의 인수의 배열

##### NewObjectV 에 필요한 추가 파라미터:

`args`:생성자 의 인수의 va_list

##### 반환값:

Java 객체를 돌려줍니다. Java 객체를 구축할 수 없었던 경우는,`NULL` 를 돌려줍니다.

##### 예외:

`InstantiationException`:클래스가 인터페이스 또는 abstract 클래스의 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

생성자 에 의해 throw 되는 모든 예외.

### GetObjectClass

`jclass GetObjectClass(JNIEnv *env, jobject obj);`

객체의 클래스를 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 31.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:Java 객체 (`null` 여서는 안 된다)

##### 반환값:

Java 클래스 객체를 돌려줍니다.

### GetObjectRefType

`jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj);`

`obj` 인수에 의해 참조되는 객체의 형태를 돌려줍니다. 인수 `obj` 는, 로컬 참조, 글로벌 참조, 약글로벌 참조의 머지않아인가입니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 232.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:로컬 참조, 글로벌 참조, 또는 약글로벌 참조.
`vm`:인터페이스 취득원의 가상 머신 인스턴스.
`env`:현재의 thread의 JNI 인터페이스 포인터의 배치 위치를 참조하는 포인터.
`version`:요구된 JNI 버젼.

##### 반환값:

함수 `GetObjectRefType` 는, `jobjectRefType` 로서 정의된 다음의 열거치의 1 개를 돌려줍니다.

> `JNIInvalidRefType = 0,`
> `JNILocalRefType = 1,`
> `JNIGlobalRefType = 2,`
> `JNIWeakGlobalRefType = 3`

인수 `obj` 가 약글로벌 참조형의 경우, 반환값은 `JNIWeakGlobalRefType` 가 됩니다.

인수 `obj` 가 글로벌 참조형의 경우, 반환값은 `JNIGlobalRefType` 가 됩니다.

인수 `obj` 가 로컬 참조형의 경우, 반환값은 `JNILocalRefType` 가 됩니다.

인수 `obj` 가 유효한 참조가 아닌 경우, 이 함수의 반환값은 `JNIInvalidRefType` 가 됩니다.

무효인 참조란, 유효한 핸들이 아닌 참조입니다. 즉,`obj` 포인터 주소는, 몇개의 Ref 작성 함수로부터 할당할 수 있었던 메모리내의 위치나 JNI 함수로부터 반환된 메모리내의 위치를 지시하고 있지 않는 참조입니다.

따라서,`NULL` 는 무효인 참조가 되어,`GetObjectRefType(env, NULL)` 은 `JNIInvalidRefType` 를 돌려줍니다.

한편, null 를 지시하는 참조인 null 참조는, 그 null 참조가 최초로 작성되었을 때의 참조의 형태를 돌려줍니다.

`GetObjectRefType` 는, 삭제된 참조에서는 사용할 수 없습니다.

참조는 일반적으로, VM 로 참조 할당 서비스에 의한 재사용의 가능성이 있는 메모리 데이터 구조의 포인터로서 구현됩니다. 따라서, 참조를 삭제하면(자) `GetObjectRefType` 의 반환값을 지정할 수 없습니다.

### IsInstanceOf

`jboolean IsInstanceOf(JNIEnv *env, jobject obj,
jclass clazz);`

객체가 클래스의 인스턴스일지 어떨지를 체크합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 32.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:Java 객체

`clazz`:Java 클래스 객체

##### 반환값:

`obj` 를 `clazz` 에 캐스트 할 수 있는 경우는,`JNI_TRUE` 를 돌려줍니다. 그렇지 않은 경우는,`JNI_FALSE` 를 돌려줍니다. `null` 객체는, 어느 클래스에도 캐스트 할 수가 있습니다.

### IsSameObject

`jboolean IsSameObject(JNIEnv *env, jobject ref1,
jobject ref2);`

2 개의 참조가 같은 Java 객체를 참조할지 어떨지를 테스트합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 24.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`ref1`:Java 객체

`ref2`:Java 객체

##### 반환값:

`ref1` 와 `ref2` 가 같은 Java 객체를 참조하는 경우, 또는 양쪽 모두가 `NULL` 의 경우는,`JNI_TRUE` 를 돌려줍니다. 그 이외의 경우는,`JNI_FALSE` 를 돌려줍니다.

## 객체의 필드에의 액세스

### GetFieldID

`jfieldID GetFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);`

클래스의 인스턴스 (비 static) 필드를 나타내는 필드 ID 를 돌려줍니다. 이 필드는, 그 이름과 시그니챠로 지정합니다. 액세스용 함수의 Get<type>Field 패밀리와 Set<type>Field 패밀리는, 필드 ID 를 사용해 객체 필드를 꺼냅니다.

`GetFieldID()` 에 의해, 아직 초기화되어 있지 않은 클래스가 초기화됩니다.

배열의 길이 필드를 얻기 위해서(때문에) `GetFieldID()` 를 사용할 수 없습니다. 대신에, `GetArrayLength()` 를 사용해 주세요.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 94.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`name`:0 로 종료하는 UTF-8 캐릭터 라인내의 필드명

`sig`:0 로 종료하는 UTF-8 캐릭터 라인내의 피르드시그니챠

##### 반환값:

필드 ID 를 돌려줍니다. 연산이 실패했을 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`NoSuchFieldError`:지정된 필드가 발견되지 않는 경우

`ExceptionInInitializerError`:예외이기 때문에, 클래스 초기화가 실패했을 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### Get<type>Field 루틴

NativeType`` Get<type>Field`(JNIEnv *env, jobject obj,
jfieldID fieldID);`

이 액세스용 루틴의 패밀리는, 객체의 인스턴스 (비 static) 필드의 값을 돌려줍니다. 액세스 해야 할 필드는, `GetFieldID()` 를 호출하는 것에 의해 얻을 수 있는 필드 ID 를 사용해 지정합니다.

다음의 겉(표)에는, Get<type>Field 루틴명과 결과의 형태가 나타나고 있습니다. Get<type>Field 내의 type 를 필드의 Java 형과 옮겨놓든가, 혹은 겉(표)의 실제의 루틴명의 1 개를 사용해,NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-1a　액세스용 루틴의 Get<type>Field 패밀리
Get>type>Field 루틴명 | 네이티브형
--- | ---
`GetObjectField()` | jobject
`GetBooleanField()` | jboolean
`GetByteField()` | jbyte
`GetCharField()` | jchar
`GetShortField()` | jshort
`GetIntField()` | jint
`GetLongField()` | jlong
`GetFloatField()` | jfloat
`GetDoubleField()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스:

겉(표) 4-1b　액세스용 루틴의 Get<type>Field 패밀리
Get>type>Field 루틴명 | 색인
--- | ---
`GetObjectField()` | 95
`GetBooleanField()` | 96
`GetByteField()` | 97
`GetCharField()` | 98
`GetShortField()` | 99
`GetIntField()` | 100
`GetLongField()` | 101
`GetFloatField()` | 102
`GetDoubleField()` | 103

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:Java 객체 (`null` 여서는 안 된다)

`fieldID`:유효 필드 ID

##### 반환값:

필드의 내용을 돌려줍니다.

### Set<type>Field 루틴

`void` Set<type>Field`(JNIEnv *env, jobject obj, jfieldID fieldID,
` NativeType `value);`

이 액세스용 루틴의 패밀리는, 객체의 인스턴스 (비 static) 필드의 값을 설정합니다. 액세스 해야 할 필드는, `GetFieldID()` 를 호출하는 것에 의해 얻을 수 있는 필드 ID 를 사용해 지정합니다.

다음의 겉(표)에는, Set<type>Field 루틴명과 결과의 형태가 나타나고 있습니다. Set<type>Field 내의 type 를 필드의 Java 형과 옮겨놓든가, 혹은 겉(표)의 실제의 루틴명의 1 개를 사용해,NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-2a　액세스용 루틴의 Set<type>Field 패밀리
Set<type>Field 루틴 | 네이티브형
--- | ---
`SetObjectField()` | jobject
S`etBooleanField()` | jboolean
`SetByteField()` | jbyte
`SetCharField()` | jchar
`SetShortField()` | jshort
`SetIntField()` | jint
`SetLongField()` | jlong
`SetFloatField()` | jfloat
`SetDoubleField()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-2b　액세스용 루틴의 Set<type>Field 패밀리
Set<type>Field 루틴 | 색인
--- | ---
`SetObjectField()` | 104
S`etBooleanField()` | 105
`SetByteField()` | 106
`SetCharField()` | 107
`SetShortField()` | 108
`SetIntField()` | 109
`SetLongField()` | 110
`SetFloatField()` | 111
`SetDoubleField()` | 112

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:Java 객체 (`null` 여서는 안 된다)

`fieldID`:유효 필드 ID

`value`:그 필드의 새로운 값

## 인스턴스 메소드의 호출

### GetMethodID

`jmethodID GetMethodID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);`

클래스 또는 인터페이스의 인스턴스 (비 static) 메소드를 나타내는 메소드 ID 를 돌려줍니다. 이 메소드는,`clazz` 의 슈퍼 클래스의 1 개 중(안)에서 정의해,`clazz` 에 의해 상속할 수 있습니다. 이 메소드는, 그 이름 및 시그니챠에 의해 결정됩니다.

`GetMethodID()` 에 의해, 아직 초기화되어 있지 않은 클래스가 초기화됩니다.

생성자 의 메소드 ID 를 가져오려면 , 메소드명으로서 `<init>` 를 지정해, 반환값의 형태로서 `void` (`V`)를 지정합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 33.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`name`:0 로 종료하는 UTF-8 캐릭터 라인내의 메소드명

`sig`:0 로 종료하는 UTF-8 캐릭터 라인내의 메소드시그니챠

##### 반환값:

메소드 ID 를 돌려줍니다. 지정된 메소드가 발견되지 않는 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`NoSuchMethodError`:지정된 메소드가 발견되지 않는 경우

`ExceptionInInitializerError`:예외이기 때문에, 클래스 초기화가 실패했을 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### Call<type>Method 루틴
Call<type>MethodA 루틴
Call<type>MethodV 루틴

NativeType`` Call<type>Method`(JNIEnv *env, jobject obj,
jmethodID methodID, ...);`

NativeType`` Call<type>MethodA`(JNIEnv *env, jobject obj,
jmethodID methodID, jvalue *args);`

NativeType`` Call<type>MethodV`(JNIEnv *env, jobject obj,
jmethodID methodID, va_list args);`

이것들 3 종류의 연산 패밀리는, 네이티브 메소드로부터 Java 인스턴스 메소드를 호출할 때에 사용됩니다. 이것들 3 종류의 패밀리는, 호출한 메소드에 파라미터를 건네주는 기구가 다를 뿐입니다.

이러한 연산 패밀리는, 지정된 메소드 ID 에 따라, Java 객체상의 인스턴스 (비 static) 메소드를 호출합니다. `methodID` 인수는,`GetMethodID``()` 를 호출하는 것에 의해 취득할 필요가 있습니다.

이러한 함수를 사용해 private 메소드나 생성자 을 호출하는 경우는, 메소드 ID 를 `obj` 의 열매 클래스의 슈퍼 클래스의 1 개로부터는 아니고, 열매 클래스 자체로부터 취득할 필요가 있습니다.

##### Call<type>Method 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후에 둡니다. Call<type>Method 루틴은, 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### Call<type>MethodA 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후의 `jvalues` 의 `args` 배열내에 둡니다. Call<type>MethodA 루틴은 이 배열내의 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### Call<type>MethodV 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후의 `va_list` 형의 `args` 인수에 넣습니다. Call<type>MethodV 루틴은, 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

다음의 겉(표)에는, 메소드 호출 루틴의 각각이 그 결과의 형태에 응해 나타나고 있습니다. Call<type>Method 내의 type 를, 호출하고 있는 메소드의 Java 형과 치환 (또는, 겉(표)의 실제의 메소드 호출 루틴명의 1 개를 사용한다), 한편 NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-3a　인스턴스 메소드 호출 루틴
Call>type>Method 루틴명 | 네이티브형
--- | ---
`CallVoidMethod()` `CallVoidMethodA()` `CallVoidMethodV()` | void
`CallObjectMethod()` `CallObjectMethodA()` `CallObjectMethodV()` | jobject
`CallBooleanMethod()` `CallBooleanMethodA()` `CallBooleanMethodV()` | jboolean
`CallByteMethod()` `CallByteMethodA()` `CallByteMethodV()` | jbyte
`CallCharMethod()` `CallCharMethodA()` `CallCharMethodV()` | jchar
`CallShortMethod()` `CallShortMethodA()` `CallShortMethodV()` | jshort
`CallIntMethod()` `CallIntMethodA()` `CallIntMethodV()` | jint
`CallLongMethod()` `CallLongMethodA()` `CallLongMethodV()` | jlong
`CallFloatMethod()` `CallFloatMethodA()` `CallFloatMethodV()` | jfloat
`CallDoubleMethod()` `CallDoubleMethodA()` `CallDoubleMethodV()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스:

겉(표) 4-3b　인스턴스 메소드 호출 루틴
Call>type>Method 루틴명 | 색인
--- | ---
`CallVoidMethod()` `CallVoidMethodA()` `CallVoidMethodV()` | 61 63 62
`CallObjectMethod()` `CallObjectMethodA()` `CallObjectMethodV()` | 34 36 35
`CallBooleanMethod()` `CallBooleanMethodA()` `CallBooleanMethodV()` | 37 39 38
`CallByteMethod()` `CallByteMethodA()` `CallByteMethodV()` | 40 42 41
`CallCharMethod()` `CallCharMethodA()` `CallCharMethodV()` | 43 45 44
`CallShortMethod()` `CallShortMethodA()` `CallShortMethodV()` | 46 48 47
`CallIntMethod()` `CallIntMethodA()` `CallIntMethodV()` | 49 51 50
`CallLongMethod()` `CallLongMethodA()` `CallLongMethodV()` | 52 54 53
`CallFloatMethod()` `CallFloatMethodA()` `CallFloatMethodV()` | 55 57 56
`CallDoubleMethod()` `CallDoubleMethodA()` `CallDoubleMethodV()` | 58 60 59

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:Java 객체

`methodID`:메소드 ID

##### Call<type>Method 루틴에 필요한 추가 파라미터:

Java 메소드에 대한 인수

##### Call<type>MethodA 루틴에 필요한 추가 파라미터:

`args`:인수의 배열

##### Call<type>MethodV 루틴에 필요한 추가 파라미터:

`args`:인수의 va_list

##### 반환값:

Java 메소드를 호출한 결과를 돌려줍니다.

##### 예외:

`Java 메소드를 실행하고 있는 동안에 발생한 예외`

### CallNonvirtual<type>Method 루틴
CallNonvirtual<type>MethodA 루틴
CallNonvirtual<type>MethodV 루틴

NativeType`` CallNonvirtual<type>Method`(JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, ...);`

NativeType`` CallNonvirtual<type>MethodA`(JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, jvalue *args);`

NativeType`` CallNonvirtual<type>MethodV`(JNIEnv *env, jobject obj,
jclass clazz, jmethodID methodID, va_list args);`

이러한 연산 패밀리는, 지정된 클래스 및 메소드 ID 에 따라, Java 객체상의 인스턴스 (비 static) 메소드를 호출합니다. `methodID` 인수는, 클래스 `clazz` 에 대해서 `GetMethodID``()` 를 호출하는 것에 의해 취득할 필요가 있습니다.

CallNonvirtual<type>Method 루틴 패밀리와 Call<type>Method 루틴 패밀리와는 다릅니다. Call<type>Method 루틴은, 객체의 클래스에 근거해 메소드를 호출합니다만,CallNonvirtual<type>Method 루틴은, 메소드 ID 를 취득할 수 있는 클래스 (`clazz` 파라미터에 의해 지정)에 근거해 메소드를 호출합니다. 메소드 ID 는, 이 객체의 열매 클래스 또는 그 열매 클래스의 슈퍼 클래스의 1 개로부터 취득하지 않으면 안됩니다.

##### CallNonvirtual<type>Method 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후에 둡니다. CallNonvirtual<type>Method 루틴은, 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### CallNonvirtual<type>MethodA 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후의 `jvalues` 의 `args` 배열내에 둡니다. CallNonvirtual<type>MethodA 루틴은 이 배열내의 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### CallNonvirtual<type>MethodV 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후의 `va_list` 형의 `args` 인수에 넣습니다. CallNonvirtualMethodV 루틴은 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

다음의 겉(표)에는, 메소드 호출 루틴의 각각이 그 결과의 형태에 응해 나타나고 있습니다. CallNonvirtual<type>Method 내의 type 를 메소드의 Java 형과 옮겨놓든가, 혹은 겉(표)의 실제의 메소드 호출 루틴명의 1 개를 사용해,NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-4a　CallNonvirtual<type>Method 루틴
CallNonvirtual>type>Method 루틴명 | 네이티브형
--- | ---
`CallNonvirtualVoidMethod()` `CallNonvirtualVoidMethodA()` `CallNonvirtualVoidMethodV()` | void
`CallNonvirtualObjectMethod()` `CallNonvirtualObjectMethodA()` `CallNonvirtualObjectMethodV()` | jobject
`CallNonvirtualBooleanMethod()` `CallNonvirtualBooleanMethodA()` `CallNonvirtualBooleanMethodV()` | jboolean
`CallNonvirtualByteMethod()` `CallNonvirtualByteMethodA()` `CallNonvirtualByteMethodV()` | jbyte
`CallNonvirtualCharMethod()` `CallNonvirtualCharMethodA()` `CallNonvirtualCharMethodV()` | jchar
`CallNonvirtualShortMethod()` `CallNonvirtualShortMethodA()` `CallNonvirtualShortMethodV()` | jshort
`CallNonvirtualIntMethod()` `CallNonvirtualIntMethodA()` `CallNonvirtualIntMethodV()` | jint
`CallNonvirtualLongMethod()` `CallNonvirtualLongMethodA()` `CallNonvirtualLongMethodV()` | jlong
`CallNonvirtualFloatMethod()` `CallNonvirtualFloatMethodA()` `CallNonvirtualFloatMethodV()` | jfloat
`CallNonvirtualDoubleMethod()` `CallNonvirtualDoubleMethodA()` `CallNonvirtualDoubleMethodV()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-4b　CallNonvirtual<type>Method 루틴
CallNonvirtual>type>Method 루틴명 | 색인
--- | ---
`CallNonvirtualVoidMethod()` `CallNonvirtualVoidMethodA()` `CallNonvirtualVoidMethodV()` | 91 93 92
`CallNonvirtualObjectMethod()` `CallNonvirtualObjectMethodA()` `CallNonvirtualObjectMethodV()` | 64 66 65
`CallNonvirtualBooleanMethod()` `CallNonvirtualBooleanMethodA()` `CallNonvirtualBooleanMethodV()` | 67 69 68
`CallNonvirtualByteMethod()` `CallNonvirtualByteMethodA()` `CallNonvirtualByteMethodV()` | 70 72 71
`CallNonvirtualCharMethod()` `CallNonvirtualCharMethodA()` `CallNonvirtualCharMethodV()` | 73 75 74
`CallNonvirtualShortMethod()` `CallNonvirtualShortMethodA()` `CallNonvirtualShortMethodV()` | 76 78 77
`CallNonvirtualIntMethod()` `CallNonvirtualIntMethodA()` `CallNonvirtualIntMethodV()` | 79 81 80
`CallNonvirtualLongMethod()` `CallNonvirtualLongMethodA()` `CallNonvirtualLongMethodV()` | 82 84 83
`CallNonvirtualFloatMethod()` `CallNonvirtualFloatMethodA()` `CallNonvirtualFloatMethodV()` | 85 87 86
`CallNonvirtualDoubleMethod()` `CallNonvirtualDoubleMethodA()` `CallNonvirtualDoubleMethodV()` | 88 90 89

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz:``` Java 클래스.

`obj`:Java 객체

`methodID`:메소드 ID

##### CallNonvirtual<type>Method 루틴에 필요한 추가 파라미터:

Java 메소드에 대한 인수

##### CallNonvirtual<type>MethodA 루틴에 필요한 추가 파라미터:

`args`:인수의 배열

##### CallNonvirtual<type>MethodV 루틴에 필요한 추가 파라미터:

`args`:인수의 `va_list`

##### 반환값:

Java 메소드를 호출한 결과를 돌려줍니다.

##### 예외:

Java 메소드를 실행하고 있는 동안에 발생한 예외

## static 필드에의 액세스

### GetStaticFieldID

`jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);`

클래스의 static 필드를 나타내는 필드 ID 를 돌려줍니다. 이 필드는, 그 이름과 시그니챠로 지정합니다. 액세스용 함수의 GetStatic<type>Field 패밀리와 SetStatic<type>Field 패밀리는, 필드 ID 를 사용해 static 필드를 꺼냅니다.

`GetStaticFieldID()` 에 의해, 아직 초기화되어 있지 않은 클래스가 초기화됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 144.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`name`:0 로 종료하는 UTF-8 캐릭터 라인내의 static 필드

`sig`:0 로 종료하는 UTF-8 캐릭터 라인내의 피르드시그니챠

##### 반환값:

필드 ID 를 돌려줍니다. 지정된 static 필드가 발견되지 않는 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`NoSuchFieldError`:지정된 static 필드가 발견되지 않는 경우

`ExceptionInInitializerError`:예외이기 때문에, 클래스 초기화가 실패했을 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### GetStatic<type>Field 루틴

NativeType`` GetStatic<type>Field`(JNIEnv *env, jclass clazz,
jfieldID fieldID);`

이 액세스용 루틴의 패밀리는, 객체의 static 필드의 값을 돌려줍니다. 액세스 하는 필드는, 필드 ID 로 지정합니다. 필드 ID 는,`GetStaticFieldID()` 를 호출하는 것에 의해 취득할 수가 있습니다.

다음의 겉(표)에는, get 루틴명의 패밀리와 결과의 형태가 나타나고 있습니다. GetStatic<type>Field 내의 type 를 필드의 Java 형과 옮겨놓든가, 혹은 겉(표)의 실제의 static 필드 액세스용 루틴명의 1 개를 사용해,NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-5a　액세스용 루틴의 GetStatic<type>Field 패밀리
GetStatic<type>Field 루틴명 | 네이티브형
--- | ---
`GetStaticObjectField``()` | jobject
`GetStaticBooleanField``()` | jboolean
`GetStaticByteField``()` | jbyte
`GetStaticCharField``()` | jchar
`GetStaticShortField``()` | jshort
`GetStaticIntField``()` | jint
`GetStaticLongField``()` | jlong
`GetStaticFloatField``()` | jfloat
`GetStaticDoubleField``()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-5b　액세스용 루틴의 GetStatic<type>Field 패밀리
GetStatic<type>Field 루틴명 | 색인
--- | ---
`GetStaticObjectField``()` | 145
`GetStaticBooleanField``()` | 146
`GetStaticByteField``()` | 147
`GetStaticCharField``()` | 148
`GetStaticShortField``()` | 149
`GetStaticIntField``()` | 150
`GetStaticLongField``()` | 151
`GetStaticFloatField``()` | 152
`GetStaticDoubleField``()` | 153

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`fieldID`:static 필드 ID

##### 반환값:

static 필드의 내용을 돌려줍니다.

### SetStatic<type>Field 루틴

`void` SetStatic<type>Field`(JNIEnv *env, jclass clazz,
jfieldID fieldID,` NativeType `value);`

이 액세스용 루틴의 패밀리는, 객체의 static 필드의 값을 설정합니다. 액세스 하는 필드는, 필드 ID 로 지정합니다. 필드 ID 는,`GetStaticFieldID()` 를 호출하는 것에 의해 취득할 수가 있습니다.

다음의 겉(표)에는, 세트 루틴명과 값의 형태가 나타나고 있습니다. SetStatic<type>Field 내의 type 를 필드의 Java 형과 옮겨놓든가, 혹은 겉(표)의 실제세트 static 필드 루틴명의 1 개를 사용해,NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-6a　액세스용 루틴의 SetStatic<type>Field 패밀리
GetStatic<type>Field 루틴명 | NativeType
--- | ---
`SetStaticObjectField``()` | jobject
`SetStaticBooleanField``()` | jboolean
`SetStaticByteField``()` | jbyte
`SetStaticCharField``()` | jchar
`SetStaticShortField``()` | jshort
`SetStaticIntField``()` | jint
`SetStaticLongField``()` | jlong
`SetStaticFloatField``()` | jfloat
`SetStaticDoubleField``()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-6b　액세스용 루틴의 SetStatic<type>Field 패밀리
GetStatic<type>Field 루틴명 | 색인
--- | ---
`SetStaticObjectField``()` | 154
`SetStaticBooleanField``()` | 155
`SetStaticByteField``()` | 156
`SetStaticCharField``()` | 157
`SetStaticShortField``()` | 158
`SetStaticIntField``()` | 159
`SetStaticLongField``()` | 160
`SetStaticFloatField``()` | 161
`SetStaticDoubleField``()` | 162

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`fieldID`:static 필드 ID

`value`:그 필드의 새로운 값

## static 메소드의 호출

### GetStaticMethodID

`jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz,
const char *name, const char *sig);`

클래스의 static 메소드를 나타내는 메소드 ID 를 돌려줍니다. 이 메소드는, 그 이름과 시그니챠로 지정합니다.

`GetStaticMethodID()` 에 의해, 아직 초기화되어 있지 않은 클래스가 초기화됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 113.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`name`:0 로 종료하는 UTF-8 캐릭터 라인내의 static 메소드명

`sig`:0 로 종료하는 UTF-8 캐릭터 라인내의 메소드시그니챠

##### 반환값:

메소드 ID 를 돌려줍니다. 연산이 실패했을 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`NoSuchMethodError`:지정된 static 메소드가 발견되지 않는 경우

`ExceptionInInitializerError`:예외이기 때문에, 클래스 초기화가 실패했을 경우

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### CallStatic<type>Method 루틴
CallStatic<type>MethodA 루틴
CallStatic<type>MethodV 루틴

NativeType`` CallStatic<type>Method`(JNIEnv *env, jclass clazz,
jmethodID methodID, ...);`

NativeType`` CallStatic<type>MethodA`(JNIEnv *env, jclass clazz,
jmethodID methodID, jvalue *args);`

NativeType`` CallStatic<type>MethodV`(JNIEnv *env, jclass clazz,
jmethodID methodID, va_list args);`

이 연산 패밀리는, 지정된 메소드 ID 에 따라, Java 객체상의 static 메소드를 호출합니다. `methodID` 인수는,`GetStaticMethodID``()` 를 호출하는 것에 의해 취득할 필요가 있습니다.

메소드 ID 는,`clazz` 의 슈퍼 클래스의 1 개로부터는 아니고,`clazz` 그 자체로부터 취득할 필요가 있습니다.

##### CallStatic<type>Method 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후에 둡니다. CallStatic<type>Method 루틴은, 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### CallStatic<type>MethodA 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후의 `jvalues` 의 `args` 배열내에 둡니다. CallStaticMethodA 루틴은 이 배열내의 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

##### CallStatic<type>MethodV 루틴

프로그래머는, 메소드에 건네주는 인수를 모두,`methodID` 인수의 직후의 `va_list` 형의 `args` 인수에 넣습니다. CallStaticMethodV 는 이러한 인수를 받아, 프로그래머가 호출하고 싶은 Java 메소드에 건네줍니다.

다음의 겉(표)에는, 메소드 호출 루틴이 각각 그 결과의 형태에 의해 나타나고 있습니다. CallStatic<type>Method 내의 type 를 메소드의 Java 형 또는 겉(표)의 실제의 메소드 호출 루틴명의 1 개로 옮겨놓는지,NativeType 를 그 루틴에 대응하는 네이티브형과 옮겨놓을 필요가 있습니다.

겉(표) 4-7a　CallStatic<type>Method 호출 루틴
CallStatic>type>Method 루틴명 | 네이티브형
--- | ---
`CallStaticVoidMethod``()` `CallStaticVoidMethodA``()` `CallStaticVoidMethod` `V()` | void
`CallStaticObjectMethod``()` `CallStaticObjectMethod` `A()` `CallStaticObjectMethod` `V()` | jobject
`CallStaticBooleanMethod``()` `CallStaticBooleanMethod` `A()` `CallStaticBooleanMethod` `V()` | jboolean
`CallStaticByteMethod``()` `CallStaticByteMethod` `A()` `CallStaticByteMethod` `V()` | jbyte
`CallStaticCharMethod``()` `CallStaticCharMethod` `A()` `CallStaticCharMethod` `V()` | jchar
`CallStaticShortMethod``()` `CallStaticShortMethod` `A()` `CallStaticShortMethod` `V()` | jshort
`CallStaticIntMethod``()` `CallStaticIntMethod` `A()` `CallStaticIntMethod` `V()` | jint
`CallStaticLongMethod``()` `CallStaticLongMethod` `A()` `CallStaticLongMethod` `V()` | jlong
`CallStaticFloatMethod``()` `CallStaticFloatMethod` `A()` `CallStaticFloatMethod` `V()` | jfloat
`CallStaticDoubleMethod``()` `CallStaticDoubleMethod` `A()` `CallStaticDoubleMethod` `V()` | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-7b　CallStatic<type>Method 호출 루틴
CallStatic>type>Method 루틴명 | 색인
--- | ---
`CallStaticVoidMethod``()` `CallStaticVoidMethodA``()` `CallStaticVoidMethod` `V()` | 141 143 142
`CallStaticObjectMethod``()` `CallStaticObjectMethod` `A()` `CallStaticObjectMethod` `V()` | 114 116 115
`CallStaticBooleanMethod``()` `CallStaticBooleanMethod` `A()` `CallStaticBooleanMethod` `V()` | 117 119 118
`CallStaticByteMethod``()` `CallStaticByteMethod` `A()` `CallStaticByteMethod` `V()` | 120 122 121
`CallStaticCharMethod``()` `CallStaticCharMethod` `A()` `CallStaticCharMethod` `V()` | 123 125 124
`CallStaticShortMethod``()` `CallStaticShortMethod` `A()` `CallStaticShortMethod` `V()` | 126 128 127
`CallStaticIntMethod``()` `CallStaticIntMethod` `A()` `CallStaticIntMethod` `V()` | 129 131 130
`CallStaticLongMethod``()` `CallStaticLongMethod` `A()` `CallStaticLongMethod` `V()` | 132 134 133
`CallStaticFloatMethod``()` `CallStaticFloatMethod` `A()` `CallStaticFloatMethod` `V()` | 135 137 136
`CallStaticDoubleMethod``()` `CallStaticDoubleMethod` `A()` `CallStaticDoubleMethod` `V()` | 138 140 139

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`methodID`:static 메소드 ID

##### CallStatic<type>Method 루틴에 필요한 추가 파라미터:

static 메소드의 인수.

##### CallStatic<type>MethodA 루틴에 필요한 추가 파라미터:

`args`:인수의 배열

##### CallStatic<type>MethodV 루틴에 필요한 추가 파라미터:

`args`:인수의 `va_list`

##### 반환값:

static Java 메소드를 호출한 결과를 돌려줍니다.

##### 예외:

`Java 메소드를 실행하고 있는 동안에 발생한 예외`

## 캐릭터 라인 조작

### NewString

`jstring NewString(JNIEnv *env, const jchar *unicodeChars,
jsize len);`

Unicode 문자 배열로부터 새로운 `java.lang.String` 객체를 구축합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 163.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`unicodeChars`:Unicode 캐릭터 라인을 참조하는 포인터

`len`:Unicode 캐릭터 라인의 길이

##### 반환값:

Java 캐릭터 라인 객체를 돌려줍니다. 캐릭터 라인을 구축할 수 없는 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### GetStringLength

`jsize GetStringLength(JNIEnv *env, jstring string);`

Java 캐릭터 라인의 길이 (Unicode 문자의 카운트)를 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 164.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`string`:Java 캐릭터 라인 객체

##### 반환값:

Java 캐릭터 라인의 길이를 돌려줍니다.

### GetStringChars

`const jchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy);`

캐릭터 라인의 Unicode 문자의 배열을 참조하는 포인터를 돌려줍니다. 이 포인터는,`ReleaseStringchars()` 가 불려 갈 때까지 유효합니다.

`isCopy` 가 `NULL` 가 아닌 경우에 카피가 작성되면(자),`*isCopy` 는 `JNI_TRUE` 로 설정됩니다. 카피가 작성되지 않는 경우는,`JNI_FALSE` 로 설정됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 165.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`string`:Java 캐릭터 라인 객체

`isCopy`:불리언 값에 대한 포인터

##### 반환값:

Unicode 캐릭터 라인을 참조하는 포인터를 돌려줍니다. 연산이 실패했을 경우는 `NULL` 를 돌려줍니다.

### ReleaseStringChars

`void ReleaseStringChars(JNIEnv *env, jstring string,
const jchar *chars);`

native code가 `chars` 에 액세스 할 필요가 없어진 것을 VM 에 알립니다. `chars` 인수는,`GetStringChars()` 를 사용해`string` 로부터 취득할 수가 있는 포인터입니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 166.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`string`:Java 캐릭터 라인 객체

`chars`:Unicode 캐릭터 라인을 참조하는 포인터

### NewStringUTF

`jstring NewStringUTF(JNIEnv *env, const char *bytes);`

UTF-8 문자의 배열로부터 새로운 `java.lang.String` 객체를 구축합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 167.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`bytes`:UTF-8 캐릭터 라인을 참조하는 포인터

##### 반환값:

Java 캐릭터 라인 객체를 돌려줍니다. 캐릭터 라인을 구축할 수 없는 경우는 `NULL` 를 돌려줍니다.

##### 예외:

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### GetStringUTFLength

`jsize GetStringUTFLength(JNIEnv *env, jstring string);`

캐릭터 라인의 UTF-8 장을 바이트로 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 168.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`string`:Java 캐릭터 라인 객체

##### 반환값:

캐릭터 라인의 UTF-8 장을 돌려줍니다.

### GetStringUTFChars

`const jbyte* GetStringUTFChars(JNIEnv *env, jstring string,
jboolean *isCopy);`

UTF-8 문자의 캐릭터 라인 배열을 참조하는 포인터를 돌려줍니다. 이 배열은,`ReleaseStringUTFChars()` 에 의해 해제될 때까지 유효합니다.

`isCopy` 가 `NULL` 가 아닌 경우에 카피가 작성되면(자),`*isCopy` 는 `JNI_TRUE` 로 설정됩니다. 카피가 작성되지 않는 경우는,`JNI_FALSE` 로 설정됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 169.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`string`:Java 캐릭터 라인 객체

`isCopy`:불리언 값에 대한 포인터

##### 반환값:

UTF-8 캐릭터 라인을 참조하는 포인터를 돌려줍니다. 연산에 실패했을 경우는,`NULL` 를 돌려줍니다.

### ReleaseStringUTFChars

`void ReleaseStringUTFChars(JNIEnv *env, jstring string,
const char *utf);`

native code가 `utf` 에 액세스 할 필요가 없어진 것을 VM 에 알립니다. `utf` 인수는,`GetStringUTFChars()` 를 사용해 `string` 로부터 취득하는 포인터입니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 170.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`string`:Java 캐릭터 라인 객체

`utf`:UTF-8 캐릭터 라인을 참조하는 포인터

## 주:

SDK/JRE 1.1 에서는, 프로그래머는 사용자가 제공하는 버퍼의 프리미티브(primitive) 배열 요소를 취득할 수 있었습니다. Java 2 SDK/JRE 1.2 이후의 버젼에서는, native code를 사용해, 사용자가 제공하는 버퍼의 Unicode 또는 UTF-8 문자를 취득할 수가 있습니다. 이후에의 예를 참조해 주세요.

### GetStringRegion

`void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);`

오프셋(offset) `start` 로 시작되는 `len` 개의 Unicode 문자를, 주어진 버퍼 `buf` 에 카피합니다.

`StringIndexOutOfBoundsException` 를 인덱스 오버플로우시에 throw 합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 220.

##### 도입된 버젼:

SDK/JRE 1.2

### GetStringUTFRegion

`Void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);`

오프셋(offset) `start` 로 시작되는 `len` 개의 Unicode 문자를 UTF-8 형식으로 변환해, 그 결과가 주어진 버퍼 `buf` 에 둡니다.

`StringIndexOutOfBoundsException` 를 인덱스 오버플로우시에 throw 합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 221.

##### 도입된 버젼:

SDK/JRE 1.2

### GetStringCritical
`` ReleaseStringCritical

`const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);
void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);`

위의 2 개의 함수의 시멘틱스는, 기존의 `Get/ReleaseStringChars` 함수를 닮아 있습니다. 가능한 경우에는, VM 는 캐릭터 라인 요소에의 포인터를 돌려줍니다. 그렇지 않은 경우, 카피가 작성됩니다. 다만, 이러한 함수의 사용 방법에 관해서 중요한 제한이 있습니다. `Get/ReleaseStringCritical` 의 호출에 의해 둘러싸이는 code segment에 대해, native code는 임의의 JNI 호출을 행하거나 현재의 thread에 블록 시켜 되지 않습니다.

`Get/ReleaseStringCritical` 의 제한은,`Get/ReleasePrimitiveArrayCritical` 의 제한 과 유사합니다.

##### 링키지 (GetStringCritical):

JNIEnv 인터페이스 함수 테이블의 인덱스 224.

##### 링키지 (ReleaseStingCritical):

JNIEnv 인터페이스 함수 테이블의 인덱스 225.

##### 도입된 버젼:

SDK/JRE 1.2

## 배열 조작

### GetArrayLength

`jsize GetArrayLength(JNIEnv *env, jarray array);`

배열내의 요소의 수를 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 171.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 배열 객체

##### 반환값:

배열의 길이를 돌려줍니다.

### NewObjectArray

`jobjectArray NewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement);`

클래스 `elementClass` 에 객체를 가지는 새로운 배열을 구축합니다. 요소는 모두, 최초로 `initialElement` 로 설정됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 172.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`length`:배열 사이즈

`elementClass`:배열 요소 클래스

`initialElement`:초기화치

##### 반환값:

Java 배열 객체를 돌려줍니다. 배열을 구축할 수 없었던 경우는 `null` 를 돌려줍니다.

##### 예외:

`OutOfMemoryError`:시스템이 메모리 부족의 경우

### GetObjectArrayElement

`jobject GetObjectArrayElement(JNIEnv *env,
jobjectArray array, jsize index);`

`Object` 배열의 요소를 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 173.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 배열

`index`:배열 첨자

##### 반환값:

Java 객체를 돌려줍니다.

##### 예외:

`ArrayIndexOutOfBoundsException`:`index` 가 배열내에 유효한 첨자의 값을 지정하지 않았던 경우

### SetObjectArrayElement

`void SetObjectArrayElement(JNIEnv *env, jobjectArray array,
jsize index, jobject value);`

`Object` 배열의 요소를 설정합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 174.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 배열

`index`:배열 첨자

`value`:새로운 값

##### 예외:

`ArrayIndexOutOfBoundsException`:`index` 가 배열내에 유효한 첨자의 값을 지정하지 않았던 경우

`ArrayStoreException`:`value` 의 클래스가, 배열의 요소 클래스의 서브 클래스가 아닌 경우

### New<PrimitiveType>Array 루틴

ArrayType`` New<PrimitiveType>Array`(JNIEnv *env, jsize length);`

새로운 프리미티브(primitive) 배열 객체를 구축하기 위해서 사용되는 연산의 패밀리. 겉(표) 4-8 에는, 특정의 프리미티브(primitive) 배열 생성자 이 나타나고 있습니다. New<PrimitiveType>Array 를, 다음의 겉(표)의 실제의 프리미티브(primitive) 배열 생성자 루틴명의 1 개로 옮겨놓아 ArrayType 를 그 루틴에 대응하는 배열형과 옮겨놓을 필요가 있습니다.

겉(표) 4-8a　배열 생성자 의 New<PrimitiveType>Array 패밀리
New<PrimitiveType>Array 루틴 | 배열형
--- | ---
`NewBooleanArray()` | jbooleanArray
`NewByteArray()` | jbyteArray
`NewCharArray()` | jcharArray
`NewShortArray()` | jshortArray
`NewIntArray()` | jintArray
`NewLongArray()` | jlongArray
`NewFloatArray()` | jfloatArray
`NewDoubleArray()` | jdoubleArray

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-8b　배열 생성자 의 New<PrimitiveType>Array 패밀리
New<PrimitiveType>Array 루틴 | 색인
--- | ---
`NewBooleanArray()` | 175
`NewByteArray()` | 176
`NewCharArray()` | 177
`NewShortArray()` | 178
`NewIntArray()` | 179
`NewLongArray()` | 180
`NewFloatArray()` | 181
`NewDoubleArray()` | 182

##### 파라미터:

`env`:JNI 인터페이스 포인터

`length`:배열장

##### 반환값:

Java 배열을 돌려줍니다. 배열을 구축할 수 없었던 경우는 `null` 를 돌려줍니다.

### Get<PrimitiveType>ArrayElements 루틴

NativeType`*`Get<PrimitiveType>ArrayElements`(JNIEnv *env,
` `ArrayType` `array, jboolean *isCopy);`

프리미티브(primitive) 배열의 본체를 돌려주는 함수의 패밀리입니다. 그 결과는, 대응하는 Release`<`PrimitiveType`>`ArrayElements() 함수가 불려 갈 때까지 유효합니다. 반환된 배열은 Java 배열의 카피인 경우도 있기 (위해)때문에, 그 반환된 배열에 더해진 변경 내용은,`Release<PrimitiveType>ArrayElements()` 가 불려 갈 때까지는, 반드시 원의 `array` 에 반영되고 있다고는 할 수 없습니다.

`isCopy` 가 `NULL` 가 아닌 경우에 카피가 작성되면(자),`*isCopy` 는 `JNI_TRUE` 로 설정됩니다. 카피가 작성되지 않는 경우는,`JNI_FALSE` 로 설정됩니다.

다음의 겉(표)에는, 특정의 프리미티브(primitive) 배열 요소 액세스 기능이 나타나고 있습니다. 다음의 치환을 실시할 필요가 있습니다.

- Get<PrimitiveType>ArrayElements 를, 겉(표)의 실제의 프리미티브(primitive) 요소 액세스 기능 루틴명의 1 개로 옮겨놓는다
- ArrayType 를 대응하는 배열형과 옮겨놓는다.
- NativeType 를, 그 루틴에 대응하는 네이티브형과 옮겨놓는다

Java VM 내에서 불 배열이 어떻게 나타내지고 있을까에 관계없이,`GetBooleanArrayElements()` 는 항상 `jbooleans` 를 참조하는 포인터를 돌려주어 옵니다. 각 바이트가 1 개의 요소를 나타내고 있습니다 (unpack 표시). 그 외의 형태의 배열은 모두, 메모리내에서 반드시 인접하게 되어 있습니다.

겉(표) 4-9a　액세스용 루틴의 Get<PrimitiveType>ArrayElements 패밀리
Get<PrimitiveType>ArrayElements 루틴 | 배열형 | 네이티브형
--- | --- | ---
`GetBooleanArrayElements()` | jbooleanArray | jboolean
`GetByteArrayElements()` | jbyteArray | jbyte
`GetCharArrayElements()` | jcharArray | jchar
`GetShortArrayElements()` | jshortArray | jshort
`GetIntArrayElements()` | jintArray | jint
`GetLongArrayElements()` | jlongArray | jlong
`GetFloatArrayElements()` | jfloatArray | jfloat
`GetDoubleArrayElements()` | jdoubleArray | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-9b　액세스용 루틴의 Get<PrimitiveType>ArrayElements 패밀리
Get<PrimitiveType>ArrayElements 루틴 | 색인
--- | ---
`GetBooleanArrayElements()` | 183
`GetByteArrayElements()` | 184
`GetCharArrayElements()` | 185
`GetShortArrayElements()` | 186
`GetIntArrayElements()` | 187
`GetLongArrayElements()` | 188
`GetFloatArrayElements()` | 189
`GetDoubleArrayElements()` | 190

##### 파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 캐릭터 라인 객체

`isCopy`:불리언 값에 대한 포인터

##### 반환값:

배열 요소를 참조하는 포인터를 돌려줍니다. 연산이 실패했을 경우는,`NULL` 를 돌려줍니다.

### Release<PrimitiveType>ArrayElements 루틴

`void` Release<PrimitiveType>ArrayElements`(JNIEnv *env,
` `ArrayType` `array,` NativeType`*elems, jint mode);`

native code가 `elems` 에 액세스 할 필요가 없는 것을 VM 에 알리는 함수의 패밀리입니다. `elems` 인수는, 대응하는 Get`<`PrimitiveType`>`ArrayElements() 함수를 사용해,`array` 로부터 취득되는 포인터입니다. 필요에 따라서, 이 함수는, `elems` 에 베풀어진 변경을 모두 원의 배열에 다시 카피합니다.

`mode` 인수는, 배열 버퍼의 해제 방법에 관한 정보를 제공합니다. `elems` 가 `array` 내의 요소의 카피가 아닌 경우,`mode` 는 영향을 미치지 않습니다. `mode` 가 `array` 내의 요소의 카피인 경우는, 다음의 겉(표)에 나타나고 있는 것 같은 영향을 미칩니다.

겉(표) 4-10 프리미티브(primitive) 배열 해제 모드
mode | 동작
--- | ---
`0` | 내용을 원의 값에 되돌려,`elems` 버퍼를 해제한다
`JNI_COMMIT` | 내용을 원의 값에 되돌리지만,`elems` 버퍼를 해제하지 않는다
`JNI_ABORT` | 변경의 가능성이 있어도 그 내용을 바탕으로 되돌리지 않고, 버퍼를 해제한다

많은 경우, 프로그래머는, 핀 배열과 카피 배열의 양쪽 모두에 대해서 일관한 동작을 보증하기 위해서, 「0」을 `mode` 인수에 건네줍니다. 0 이외를 건네주는 경우는, 프로그래머는 메모리를 충분히 주의해 관리할 필요가 있습니다.

다음의 겉(표)에는, 프리미티브(primitive) 배열 처치 기능의 패밀리를 구성하는 특정의 루틴이 나타나고 있습니다. 다음의 치환을 실시할 필요가 있습니다.

- Release<PrimitiveType>ArrayElements 를,겉(표) 4-11 에 나타나고 있는 실제의 프리미티브(primitive) 배열 처치 기능 루틴명의 1 개로 옮겨놓는다.
- ArrayType 를 대응하는 배열형과 옮겨놓는다.
- NativeType 를, 그 루틴에 대응하는 네이티브형과 옮겨놓는다

겉(표) 4-11a　배열 루틴의 Release<PrimitiveType>ArrayElements 패밀리
Release<PrimitiveType>ArrayElements 루틴 | 배열형 | 네이티브형
--- | --- | ---
`ReleaseBooleanArrayElements()` | jbooleanArray | jboolean
`ReleaseByteArrayElements()` | jbyteArray | jbyte
`ReleaseCharArrayElements()` | jcharArray | jchar
`ReleaseShortArrayElements()` | jshortArray | jshort
`ReleaseIntArrayElements()` | jintArray | jint
`ReleaseLongArrayElements()` | jlongArray | jlong
`ReleaseFloatArrayElements()` | jfloatArray | jfloat
`ReleaseDoubleArrayElements()` | jdoubleArray | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-11b　배열 루틴의 Release<PrimitiveType>ArrayElements 패밀리
Release<PrimitiveType>ArrayElements 루틴 | 색인
--- | ---
`ReleaseBooleanArrayElements()` | 191
`ReleaseByteArrayElements()` | 192
`ReleaseCharArrayElements()` | 193
`ReleaseShortArrayElements()` | 194
`ReleaseIntArrayElements()` | 195
`ReleaseLongArrayElements()` | 196
`ReleaseFloatArrayElements()` | 197
`ReleaseDoubleArrayElements()` | 198

##### 파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 배열 객체

`elems`:배열 요소를 참조하는 포인터

`mode`:해제 모드

### Get<PrimitiveType>ArrayRegion 루틴

void`` Get<PrimitiveType>ArrayRegion`(JNIEnv *env,` ArrayType `array,
jsize start, jsize len,` NativeType`*buf);`

프리미티브(primitive) 배열의 영역을 버퍼에 카피하는 함수의 패밀리입니다.

다음의 겉(표)에는, 특정의 프리미티브(primitive) 배열 요소 액세스 기능이 나타나고 있습니다. 다음의 치환을 실시할 필요가 있습니다.

- Get<PrimitiveType>ArrayRegion 를,겉(표) 4-12 에 나타나고 있는 실제의 프리미티브(primitive) 요소 액세스 기능 루틴명의 1 개로 옮겨놓는다.
- ArrayType 를 대응하는 배열형과 옮겨놓는다
- NativeType 를, 그 루틴에 대응하는 네이티브형과 옮겨놓는다

겉(표) 4-12a　배열 액세스 기능 루틴의 Get<PrimitiveType>ArrayRegion 패밀리
Get<PrimitiveType>ArrayRegion 루틴 | 배열형 | 네이티브형
--- | --- | ---
`GetBooleanArrayRegion()` | jbooleanArray | jboolean
`GetByteArrayRegion()` | jbyteArray | jbyte
`GetCharArrayRegion()` | jcharArray | jchar
`GetShortArrayRegion()` | jshortArray | jhort
`GetIntArrayRegion()` | jintArray | jint
`GetLongArrayRegion()` | jlongArray | jlong
`GetFloatArrayRegion()` | jfloatArray | jloat
`GetDoubleArrayRegion()` | jdoubleArray | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-12b　배열 액세스 기능 루틴의 Get<PrimitiveType>ArrayRegion 패밀리
Get<PrimitiveType>ArrayRegion 루틴 | 색인
--- | ---
`GetBooleanArrayRegion()` | 199
`GetByteArrayRegion()` | 200
`GetCharArrayRegion()` | 201
`GetShortArrayRegion()` | 202
`GetIntArrayRegion()` | 203
`GetLongArrayRegion()` | 204
`GetFloatArrayRegion()` | 205
`GetDoubleArrayRegion()` | 206

##### 파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 배열

`start`:개시 첨자

`len`:카피 대상의 요소의 수

`buf`:전송처 버퍼

##### 예외:

`ArrayIndexOutOfBoundsException`:영역내의 첨자의 1 개에서도 유효하지 않는 경우

### Set<PrimitiveType>ArrayRegion 루틴

`void` Set<PrimitiveType>ArrayRegion`(JNIEnv *env,` ArrayType `array,
jsize start, jsize len,` NativeType`*buf);`

버퍼로부터의 프리미티브(primitive) 배열의 영역을 원의 값에 되돌리는 함수의 패밀리입니다.

다음의 겉(표)에는, 특정의 프리미티브(primitive) 배열 요소 액세스 기능이 나타나고 있습니다. 다음의 치환을 실시할 필요가 있습니다.

- Set<PrimitiveType>ArrayRegion 를, 겉(표)의 실제의 프리미티브(primitive) 요소 액세스 기능 루틴명의 1 개로 옮겨놓는다
- ArrayType 를 대응하는 배열형과 옮겨놓는다.
- NativeType 를, 그 루틴에 대응하는 네이티브형과 옮겨놓는다

  겉(표) 4-13a　배열 액세스 기능 루틴의 Set<PrimitiveType>ArrayRegion 패밀리
  Set<PrimitiveType>ArrayRegion 루틴 | 배열형 | 네이티브형
  --- | --- | ---
  `SetBooleanArrayRegion()` | jbooleanArray | jboolean
  `SetByteArrayRegion()` | jbyteArray | jbyte
  `SetCharArrayRegion()` | jcharArray | jchar
  `SetShortArrayRegion()` | jshortArray | jshort
  `SetIntArrayRegion()` | jintArray | jint
  `SetLongArrayRegion()` | jlongArray | jlong
  `SetFloatArrayRegion()` | jfloatArray | jfloat
  `SetDoubleArrayRegion()` | jdoubleArray | jdouble

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스.

겉(표) 4-13b　배열 액세스 기능 루틴의 Set<PrimitiveType>ArrayRegion 패밀리
Set<PrimitiveType>ArrayRegion 루틴 | 색인
--- | ---
`SetBooleanArrayRegion()` | 207
`SetByteArrayRegion()` | 208
`SetCharArrayRegion()` | 209
`SetShortArrayRegion()` | 210
`SetIntArrayRegion()` | 211
`SetLongArrayRegion()` | 212
`SetFloatArrayRegion()` | 213
`SetDoubleArrayRegion()` | 214

파라미터:

`env`:JNI 인터페이스 포인터

`array`:Java 배열

`start`:개시 첨자

`len`:카피 대상의 요소의 수

`buf`:전송원버퍼

##### 예외:

`ArrayIndexOutOfBoundsException`:영역내의 첨자의 1 개에서도 유효하지 않는 경우

## 주:

SDK/JRE 1.1 에서는, 프로그래머는 `Get/ReleaseArrayElements` 함수를 사용해, 프리미티브(primitive) 배열 요소에의 포인터를 취득할 수 있었습니다. VM 가 피닝을 지원하고 있는 경우, 원의 데이터에의 포인터가 돌려주어졌습니다. 지원하고 있지 않는 경우에는, 카피가 작성되었습니다.

SDK/JRE 1.3 에 도입된 새로운 함수를 사용하면(자), VM 가 피닝을 지원하고 있지 않는 경우에서도, native code는 배열 요소에의 직접 포인터를 취득할 수가 있습니다.

### GetPrimitiveArrayCritical
ReleasePrimitiveArrayCritical

`void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);
void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);`

위의 2 개의 함수의 시멘틱스는, 기존의 `Get/Release<PrimitiveType>ArrayElements` 함수와 매우 자주(잘) 닮았습니다. 가능한 경우는, VM 는 프리미티브(primitive) 배열에의 포인터를 돌려줍니다. 그렇지 않은 경우는, 카피가 작성됩니다. 다만, 이러한 함수의 사용 방법에 관해서 중요한 제한이 있습니다.

`GetPrimitiveArrayCritical` 를 호출한 뒤,`ReleasePrimitiveArrayCritical` 를 호출하기 전에, native code를 특정의 기간 실행하지 않게 합니다. 이 1 조의 함수 내부의 코드는 「위기 리젼」으로 실행되고 있는 것으로서 취급할 필요가 있습니다. 위기 리젼 내부에 있어 native code는, 다른 JNI 함수를 호출해 안되어, 현재의 thread에 다른 Java thread를 블록 해 대기시키는 것을 가능하게 하는 어느 시스템 콜도 호출해서는 안됩니다. 예를 들어, 현재의 thread는, 다른 Java thread가 기술한 스트림상의 `read` 를 호출해서는 안됩니다.

이러한 제한은, VM 가 피닝을 지원하지 않는 경우에서도, native code가 배열의 카피되어 있지 않은 버젼을 취득할 가능성을 높입니다. 예를 들어, native code가 `GetPrimitiveArrayCritical` 에 의해 취득된 배열에의 포인터를 보관 유지하고 있는 경우, VM 는 일시적으로 가베지 컬렉션을 무효로 하는 일이 있습니다.

`GetPrimtiveArrayCritical` 및 `ReleasePrimitiveArrayCritical` 의 복수의 편성은, 상자로 할 수 있습니다. 예를 나타냅니다.

      jint len = (*env)->GetArrayLength(env, arr1);
      jbyte *a1 = (*env)->GetPrimitiveArrayCritical(env, arr1, 0);
      jbyte *a2 = (*env)->GetPrimitiveArrayCritical(env, arr2, 0);
      /* We need to check in case the VM tried to make a copy.  */
      if (a1 == NULL || a2 == NULL) {
        ... /* out of memory exception thrown */
      }
      memcpy(a1, a2, len);
      (*env)->ReleasePrimitiveArrayCritical(env, arr2, a2, 0);
      (*env)->ReleasePrimitiveArrayCritical(env, arr1, a1, 0);

VM 가 내부적으로 다른 형식에서 배열을 나타내는 경우,`GetPrimitiveArrayCritical` 는 아직 배열의 카피를 작성할 가능성이 있습니다. 그 때문에, 일어날 수 있는 메모리 부족의 상황에 대응해 `null` 에 대한 반환값을 체크할 필요가 있습니다.

##### 링키지 (GetPrimitiveArrayCritical):

JNIEnv 인터페이스 함수 테이블의 링키지 인덱스 222.

##### 링키지 (ReleasePrimitiveArrayCritical):

JNIEnv 인터페이스 함수 테이블의 링키지 인덱스 223.

##### 도입된 버젼:

SDK/JRE 1.2

## 네이티브 메소드의 등록

### RegisterNatives

`jint RegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods, jint nMethods);`

`clazz` 인수에 의해 지정된 클래스에 네이티브 메소드를 등록합니다. `methods` 파라미터는, 그 네이티브 메소드의 이름, 시그니챠, 함수 포인터를 포함한 `JNINativeMethod` 구조체의 배열을 지정합니다. `nMethods` 파라미터는, 배열내의 네이티브 메소드의 수를 지정합니다. `JNINativeMethod` 구조체는 다음과 같이 정의됩니다.

    typedef struct {

        char *name;

        char *signature;

        void *fnPtr;

    } JNINativeMethod;

함수 포인터는, 형식상, 다음의 시그니챠를 갖추고 있을 필요가 있습니다.

    ReturnType (*fnPtr)(JNIEnv *env, jobject objectOrClass, ...);

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 215.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

`methods`:클래스내의 네이티브 메소드

`nMethods`:그 클래스내의 네이티브 메소드의 수

##### 반환값:

성공의 경우는 「0」을, 실패의 경우는 0 보다 작은 값을 돌려줍니다.

##### 예외:

`NoSuchMethodError`:지정된 메소드가 발견되지 않았던 경우, 또는, 그 메소드가 네이티브는 아니었던 경우

### UnregisterNatives

`jint UnregisterNatives(JNIEnv *env, jclass clazz);`

어느 클래스의 네이티브 메소드의 등록을 해제합니다. 그 클래스는, 그 네이티브 메소드 기능에 링크되기 전 또는 재등록되기전 상태에 돌아옵니다.

이 함수는, 일반적으로의 native code에서는 사용해야 하는 것이 아닙니다. 그 대신에, 특별한 프로그램에 네이티브 라이브러리를 재로드하거나재링크하거나 하는 방법을 제공합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 216.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`clazz`:Java 클래스 객체

##### 반환값:

성공의 경우는 「0」을, 실패의 경우는 0 보다 작은 값을 돌려줍니다.

## 모니터 오퍼레이션

### MonitorEnter

`jint MonitorEnter(JNIEnv *env, jobject obj);`

`obj` 에 의해 참조되는 기저의 Java 객체에 관련하는 모니터에 들어갑니다.

Java 객체는 각각, 관련하는 모니터를 가지고 있습니다. 현재의 thread가 벌써 `obj` 에 관련하는 모니터를 가지는 경우는, 이 thread가 모니터에 들어간 회수를 나타내는 모니터내의 카운터가 증가됩니다. `obj` 에 관련하는 모니터가 어느 thread에도 소유되어 있지 않은 경우는, 현재의 thread가 그 모니터의 소유자가 되어, 이 모니터의 엔트리 카운트를 1 으로 설정합니다. 다른 thread가 벌써 `obj` 에 관련하는 모니터를 소유하고 있는 경우, 현재의 thread는 모니터가 해제되는 것을 기다려, 재차, 소유권을 획득하려고 합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 217.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:일반적으로의 Java 객체 또는 클래스 객체

##### 반환값:

성공의 경우는 「0」을, 실패의 경우는 0 보다 작은 값을 돌려줍니다.

### MonitorExit

`jint MonitorExit(JNIEnv *env, jobject obj);`

현재의 thread는,`obj` 에 의해 참조된 기저의 Java 객체에 관련하는 모니터의 소유자가 아니면 안됩니다. 이 thread는, 이 모니터에 들어간 회수를 나타내는 카운터를 감소시킵니다. 카운터의 값이 제로가 되면(자), 현재의 thread는 모니터를 해제합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 218.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`obj`:일반적으로의 Java 객체 또는 클래스 객체

##### 반환값:

성공의 경우는 「0」을, 실패의 경우는 0 보다 작은 값을 돌려줍니다.

## NIO 의 지원

NIO 관련의 엔트리 포인트에 의해, native code가 `java.nio`「직접 버퍼」에 액세스 할 수 있습니다. 직접 버퍼의 컨텐츠는, 일반적으로의 가베지 컬렉트된 heap의 외측의, 네이티브메모리내에 포함할 수가 있습니다. 직접 버퍼에 대한 자세한 것은, 「New I/O API 」 및 `java.nio.ByteBuffer` 클래스의 스펙을 참조해 주세요.

SDK/JRE 1.4 에 도입된 3 개(살)의 새로운 함수에 의해, 직접 버퍼를 JNI 코드로 작성, 검사, 및 조작할 수가 있습니다.

- `NewDirectByteBuffer`
- `GetDirectBufferAddress`
- `GetDirectBufferCapacity`

Java 가상 머신의 각 구현에서는 이러한 함수를 지원할 필요가 있습니다만, 모든 구현이 직접 버퍼에의 JNI 의 액세스를 지원할 필요는 없습니다. JVM 가 이러한 액세스를 지원하지 않는 경우는,`NewDirectByteBuffer` 및 `GetDirectBufferAddress` 함수는 항상 `null` 를 돌려주어,`GetDirectBufferCapacity` 함수는 항상 `-1` 을 돌려줍니다. JVM 가 이러한 액세스를 지원하는 경우, 각 함수는 적절한 값을 돌려주도록(듯이) 구현될 필요가 있습니다.

### NewDirectByteBuffer

`jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);`

메모리아드레스 `address` 로부터 시작되는 `capacity` 바이트까지의 메모리브록크를 참조해, 직접 버퍼 `java.nio.ByteBuffer` 를 할당해 돌려줍니다.

이 함수를 호출해, Java 레벨의 코드에 최종적인 바이트 버퍼의 객체를 돌려주는 native code는, 그 버퍼가, read와 적절한 경우에는 서두의 액세스가 가능한, 유효한 메모리 영역을 참조할 필요가 있습니다. Java 코드로부터 무효인 메모리 위치에 액세스 하려고 하면(자), 시각 효과가 없는 임의의 값을 돌려주는지, 지정되어 있지 않은 예외가 발생합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 229.

##### 파라미터:

`env`:`JNIEnv` 의 인터페이스 포인터

`address`:메모리 영역의 개시 주소 (`null` 는 불가)

`capacity`:메모리 영역의 바이트수로 가리킨 사이스 (정의 수인 것)

##### 반환값:

신규에 인스턴스화 된 `java.nio.ByteBuffer` 객체의 로컬 참조를 돌려줍니다. 예외가 발생하거나 이 가상 머신이, 직접 버퍼에의 JNI 의 액세스를 지원하고 있지 않는 경우는,`null` 를 돌려줍니다.

##### 예외:

`OutOfMemoryError`:`ByteBuffer` 객체의 할당해에 실패했을 경우

#####

##### 도입된 버젼:

SDK/JRE 1.4

### GetDirectBufferAddress

`void* GetDirectBufferAddress(JNIEnv* env, jobject buf);`

지정된 직접 버퍼 `java.nio.Buffer` 에 참조되는 메모리 영역의 개시 주소를 페치 해, 돌려줍니다.

이 함수에 의해, native code는, Java 코드가 버퍼 객체를 개입시켜 액세스 할 수 있는 메모리 영역과 같은 메모리 영역에 액세스 할 수 있게 됩니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 230.

##### 파라미터:

`env`:`JNIEnv` 의 인터페이스 포인터

`buf`:직접 버퍼 `java.nio.Buffer` 객체 (`null` 는 불가)

##### 반환값:

버퍼에 참조되는 메모리 영역의 개시 주소를 돌려줍니다. 메모리 영역이 미정도리의 경우, 지정된 객체가 직접 버퍼의 `java.nio.Buffer` 객체가 아닌 경우, 또는, 직접 버퍼에의 JNI 의 액세스가 이 가상 머신으로 지원되어 있지 않은 경우는,`null` 를 돌려줍니다.

#####

##### 도입된 버젼:

SDK/JRE 1.4

### GetDirectBufferCapacity

`jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf);`

지정된 직접 버퍼 `java.nio.Buffer` 에 참조되는 메모리 영역의 바이트수로 가리킨 사이즈를 페치 해, 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 231.

##### 파라미터:

`env`:`JNIEnv` 의 인터페이스 포인터

`buf`:직접 버퍼 `java.nio.Buffer` 객체 (`null` 는 불가)

##### 반환값:

버퍼에 관련지을 수 있었던 메모리 영역의 사이즈를 바이트수로 돌려줍니다. 지정된 객체가 직접 버퍼의 `java.nio.Buffer` 객체가 아닌 경우, 또는, 직접 버퍼에의 JNI 의 액세스가 이 가상 머신으로 지원되어 있지 않은 경우는,`-1` 을 돌려줍니다.

#####

##### 도입된 버젼:

SDK/JRE 1.4

## 리플렉션의 지원

프로그래머는, 메소드 또는 필드의 이름 및 형태를 파악하고 있는 경우, JNI 를 사용해 Java 메소드의 호출해 또는 Java 필드에의 액세스를 실시할 수가 있습니다. Java Core Reflection API 를 사용하면(자), 프로그래머는 실행시에 Java 클래스의 내부를 조사할 수가 있습니다. JNI 는, JNI 로 사용되는 필드와 메소드 ID 및 Java Core Reflection API 로 사용되는 메소드 객체의 사이의 변환 함수세트를 제공합니다.

### FromReflectedMethod

`jmethodID FromReflectedMethod(JNIEnv *env, jobject method);`

`java.lang.reflect.Method` 또는 `java.lang.reflect.Constructor` 객체를 메소드 ID 로 변환합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 7.

##### 도입된 버젼:

>SDK/JRE 1.2

### FromReflectedField

`jfieldID FromReflectedField(JNIEnv *env, jobject field);`

`java.lang.reflect.Field` 를 필드 ID 로 변환합니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 8.

##### 도입된 버젼:

SDK/JRE 1.2

### ToReflectedMethod

`jobject ToReflectedMethod(JNIEnv *env, jclass cls,
jmethodID methodID);`

`cls` 로부터 취득한 메소드 ID 를 `java.lang.reflect.Method` 또는 `java.lang.reflect.Constructor` 객체로 변환합니다.

변환에 실패했을 경우에는,`OutOfMemoryError` 를 throw 해, 0 을 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 9.

##### 도입된 버젼:

SDK/JRE 1.2

### ToReflectedField

`jobject ToReflectedField(JNIEnv *env, jclass cls,
jfieldID fieldID);`

`cls` 로부터 취득한 필드 ID 를 `java.lang.reflect.Field` 객체로 변환합니다.

변환에 실패했을 경우에는,`OutOfMemoryError` 를 throw 해, 0 을 돌려줍니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 12.

##### 도입된 버젼:

SDK/JRE 1.2

## Java VM 인터페이스

### GetJavaVM

`jint GetJavaVM(JNIEnv *env, JavaVM **vm);`

현재의 thread에 관련하는 Java VM 인터페이스 (호출 API 로 사용)를 돌려줍니다. 그 결과는, 2 번째의 인수 `vm` 로 나타난 위치에 놓여집니다.

##### 링키지:

JNIEnv 인터페이스 함수 테이블의 인덱스 219.

##### 파라미터:

`env`:JNI 인터페이스 포인터

`vm`:결과를 돌려주는 포인터

##### 반환값:

성공의 경우는 「0」을, 실패의 경우는 0 보다 작은 값을 돌려줍니다.

목차 | 전의 항목 | 다음의 항목 |

Copyright © 2003 Sun Microsystems, Inc. All rights reserved.