JNI ���� ǥ�� �������̽� �Լ����� �ִ�. �̰��� �̿��ؼ� Java ��ü�� ���� �� �����ϰ�, ��ü�� �ҵ忡 ������ �� �ְ� �ȴ�. ������� �̷��� �Լ����� ����ϴ� ����� ���ؼ� �����Ѵ�.
JNI�� ���ڿ��� ��ȯ�� �� �ִ� �Լ��� �����Ѵ�. �̸� �̿��ؼ� Unicode�� UTF-8 �������� ǥ���� ���ڿ��� ��ȯ�� �� �ֵ��� �Ѵ�.
������� �迭�� �����ϰ�, �迭�� ���ҿ� ������ �� �ִ� ����� �����Ѵ�.
JNI������ ��callback���� �̿��ؼ� native �ڵ�κ��� Java �ҵ带 ȣ���� �� �ְ� �ȴ�. javap�� �̿��ϰ� �Ǹ�, Ŭ���� ���Ϸκ��� JNI ��Ÿ���� �ҵ� ǥ���� ������ �� �ִ�.
���� ���������� ��� ������ ���� ������ �� �� �ִ� ����� JNI ���� �����Ѵ�. javap�� �̿��ϰ� �Ǹ� ���������� JNI ��Ÿ���� ��� ���� ǥ���� ���� �� �ִ�.
������� ���� ���� ���� �ٷ�� ����� �Ұ��ȴ�. native ���α������� catch, throw, clear ���� ���� ó���� �� �� �ִ�.
native �ڵ尡 Java ��ü�� ������ �� �ִ� ����� local�� global �� �����̴�. local�� ��쿡�� native �Լ� �������� ������ �����ϰ� �ǰ�, �����ϰ� �Ǹ� �����ȴ�. global�� ��쿡�� ���α� ��ü���� ������ �� �ְ� �ȴ�.
������� ��Ƽ������ ������ native �ҵ带 �����ϴ� �Ϳ� ���� �����ȴ�. JNI������ �⺻���� ����ȭ ����� �����ȴ�.
C++������ �� �� ������ �������̽��� ����� �� �ְ�, �߰����� Ÿ�� üũ�� �� �� �ִ�.
C�� (char *) Ÿ���� jstring Ÿ�� ȣȯ�� ���� ����. ���Ƿ�, Java ���ڿ��� native ���ڿ��� ��ȯ���� �� �ִ� �Լ��� �ʿ��ϴ�. Java�� UTF-8 Ÿ���� ���ڿ��� Unicode�ʹ� �� ASCII ���ڿ��� ȣȯ�� �����ϴ�.
Unicode�� UTF-8 Ÿ���� ���ڿ��� ��ȯ���ִ� ���� GetStringUTFChars�� ��������ν� ����������. ���� �������� ���� Ȯ���غ� �� �ִ�.
#include <stdio.h>
#include <jni.h>
#include "Prompt.h"
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv
*env, jobject obj, jstring prompt)
{
char buf[128];
const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
printf("%s", str);
(*env)->ReleaseStringUTFChars(env,
prompt, str);
scanf("%s", buf);
return (*env)->NewStringUTF(env,
buf);
}
return ���� ���� �Ǹ� native ���α������� Java���� ����� �� �ִ� ���ڿ��� ������ �������� �� �� �ִ�. ��, NewStringUTF() �Լ��� ����ϸ� �ȴ�.
native �ҵ�� env �������̽� ������ �̿��ؼ� Java ��ü�� �����ϰų� �ٷ��� �Ѵ�. ���� ���� �� ������ ������ ��Ÿ���� ���̴�.
������ �� ���� ������ ���ڿ� ���� �Լ��̴�.
jarray�� jstring�� ���������� native �ҵ忡�� �����ϱ� ���ؼ��� ��ȯ������ �ʿ��ϴ�.
������ Java ���α��� ������ �迭�� native �ҵ�� �Ѱ��ִ� ��� �Լ��� ������ �ִ�.
class IntArray {
private native int sumArray(int
arr[]);
public static void main(String args[]) {
IntArray p = new IntArray();
int arr[] = new int
[10];
for (int i = 0; i < 10; i++)
arr[i] = i;
int sum = p.sumArray(arr);
System.out.println("sum = " + sum);
}
static
{
System.loadLibrary("MyImpOfIntArray");
}
}
���� C ���α������� ���� �������� �Ѱܹ��� �迭�� ó���ؼ� �ٽ� �����ϴ� ������ �����ش�.
#include <jni.h>
#include "IntArray.h"
JNIEXPORT jint JNICALL
Java_IntArray_sumArray(JNIEnv *env,
jobject obj, jintArray arr)
{
jsize len = (*env)->GetArrayLength(env,
arr);
int i, sum = 0;
jint *body = (*env)->GetIntArrayElements(env,
arr, 0);
for (i=0; i<len; i++) {
sum
+= body[i];
}
(*env)->ReleaseIntArrayElements(env,
arr, body, 0);
return sum;
}
�����ؼ� �� �κ��� GetIntArrayLength(), GetIntArrayElements(),
ReleaseIntArrayElements() �Լ��̴�. Get<type>ArrayElements() �Լ��� Java�κ���
���� �迭�� C���� ����� �� �ֵ��� ��ȯ���ִ� �Լ��̰�, Release<type>ArrayElements()
�Լ��� �װ��� �������ִ� �Լ��̴�. �� ¦�� �̷M ����� �� �ֵ��� �����ؾ�
�Ѵ�. Get<type>ArrayLength() �Լ��� �̿��ؼ� �迭�� ���̵� ���غ� �� �ִ�.
���� �� ���� ǥ�� �迭�� ��ȯ���ְų� �������ִ� �Լ��� ������ ���̴�.
Function |
Array Type |
GetBooleanArrayElements |
boolean |
GetByteArrayElements |
byte |
GetCharArrayElements |
char |
GetShortArrayElements |
short |
GetIntArrayElements |
int |
GetLongArrayElements |
long |
GetFloatArrayElements |
float |
GetDoubleArrayElements |
double |
JNI Functions for Accessing Arrays
Function |
Array Type |
ReleaseBooleanArrayElements |
boolean |
ReleaseByteArrayElements |
byte |
ReleaseCharArrayElements |
char |
ReleaseShortArrayElements |
short |
ReleaseIntArrayElements |
int |
ReleaseLongArrayElements |
long |
ReleaseFloatArrayElements |
float |
ReleaseDoubleArrayElements |
double |
JNI Functions for Releasing Arrays
Get<type>ArrayElements() �Լ��� �迭 ��ü�� �����ؿ��� ������ �Ѵ�. �뵵�� ���� �迭 ��ü�� ����� �ʿ䰡 ���� �Ϻκи��� ������ �ʿ䵵 ���� �� �ִ�. �� ��쿡�� Get/Set<type>ArrayRegion() �Լ��� ����� �� �ִ�.
��ü�� �迭�� ������ �� �ִ�. ������, �ѹ��� ��� ��ü�� �迭�� ������ ���� ����.
���� �������� Java Method�� ȣ���ϴ� ����� �����Ѵ�. Java ���α����� ȣ���� native �ҵ忡�� �ٽ� Java �ҵ带 ȣ���ϴ� ������ �����Ѵ�. 5�� �ݺ��ؼ� ȣ���� �ڿ� �����ϰ� �ȴ�.(���� ������ ������ �ݺ��ؼ� ȣ���ϰ� �ȴ�.)
class Callbacks {
private native void nativeMethod(int
depth);
private void callback(int depth) {
if (depth < 5) {
System.out.println("In
Java, depth = " + depth + ", about to enter C");
nativeMethod(depth + 1);
System.out.println("In
Java, depth = " + depth + ", back from C");
} else
System.out.println("In Java,
depth = " + depth + ", limit exceeded");
}
public static void main(String args[]) {
Callbacks
c = new Callbacks();
c.nativeMethod(0);
}
static {
System.loadLibrary("MyImpOfCallbacks");
}
}
native �ڵ�� ������ ����. native �ҵ忡���� �ٽ� Java �ҵ带 �ٽ� ȣ���ϰ� �ȴ�.
#include <stdio.h>
#include <jni.h>
#include "Callbacks.h"
JNIEXPORT void JNICALL
Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID
mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
if (mid == 0) {
return;
}
printf("In C, depth = %d, about to enter Java\n", depth);
(*env)->CallVoidMethod(env, obj, mid, depth);
printf("In
C, depth = %d, back from Java\n", depth);
}
Java
�ҵ带 ȣ���ϱ� ���� �ܰ�� �������� �̷�����.
�ҵ��� �̸��� UTF-8 �������� ǥ���� Java �ҵ��� �̸��̴�.
�������� ���� Ư����, <init>�� ǥ���ȴ�.
�ҵ��� Ÿ���� ��(argument-type)return-type�� ���·� ǥ���� �Ǹ�, ��
Ÿ���� ��Ÿ���� ���� ���� ǥ�� ����.
signature |
Java Programming Language Type |
Z |
Boolean |
B |
byte |
C |
char |
S |
short |
I |
int |
J |
long |
F |
float |
D |
double |
L fully-qualified-class; |
fully-qulified-class |
[ type |
type[] |
(arg-types)ret-type |
method type |
Java VM Type Signatures
���� ���, ([Ljava/lang/String;)V ��� ǥ���� �Ǿ��ٰ� �ϸ�, ���� Ÿ���� void�̰�, ���ڷ� String ��ü�� �迭�� �Ѱ����ٴ� �ǹ̰� �ȴ�.
javap�� �̿��ϸ�, ������ Ÿ���� Ȯ���غ� �� �־, Ÿ�� ������ ���� �Ǽ��� ������ �� �ִ�.
�ҵ� ID�� �� ����ϰ� �Ǹ�, �ݺ��Ǿ ȣ���ؾ� �ϴ� �Լ��� ���ؼ� ȿ�������� ����� �� �ִ�. �ҵ� ID�� Ŭ������ unload�Ǹ�, ����� �� ���� �ȴٴ� ���� �����ؾ� �Ѵ�. unload�� ���Ŀ��� ����� �� �ֵ��� �ϱ� ���ؼ��� �ڿ� ������ Local and Global References���� ������ ���� �� �ִ�.
Java �ҵ�� ���ڸ� �Ѱ��ִ� ������� ���������� �ִ�. ��κ� �ҵ� ID �ڿ� ���ڸ� �ٿ��� �ѱ�� ����̴�. �տ��� �Ұ��� ����� CallVoidMethod() �Լ��� �̿��� ���̾���. �� �ۿ��� �� ������ �Ǵٸ� ����� �����ϴµ� �̰��� �ٷ� CallVoidMethodV()�� CallVoidMethodA()�� �װ��̴�. ������ ��쿡�� va_list��� ���ڸ� �Ѱ��ְ� �ȴ�. �̰��� ���� ���� ���ڸ� �Ѱ��� �� �ֵ��� ���ǵ� Ư���� Ÿ���̴�. ������ ��쿡�� jvalue��� �Ҹ��� union Ÿ���� �迭�� �Ѱ��ִ� ����̴�. jvalue�� ������ ���� ���ǵǾ� �ִ�.
typedef union jvalue {
jboolean
z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject
l;
} jvalue;
�߰�������, �Լ��� ���ϰ��� ���� �Լ��� �����ȴ�. CallBooleanMethod(), CallIntMethod() ���� �̷��� ���� ���� �ȴ�.
class �ҵ嵵 �Ϲ� Java �ҵ带 ȣ���ϴ� ����� �����ϰ� ȣ���Ѵ�. ������ ���� �ܰ踦 ��ġ�� �ȴ�. GetStaticMethodID() �Լ��� �̿��ؼ� �ҵ� ID�� ����. CallStaticVoidMethod(), CallStaticBooleanMethod() ���� �Լ��� �̿��ؼ� ���ϴ� class �ҵ带 ȣ���Ѵ�.
superclass�� ȣ���ϱ� ���ؼ��� CallNonvirtual<type>Method�� �̿��Ѵ�. ������ ���� �ܰ踦 ��ġ�� �ȴ�.
superclass�� �ҵ带 ȣ���ϴ� ���� ���� �������� �ʴ´�.
JNI���� instance�� class ������ ���ؼ� ������ �� �ִ� ����� �����Ѵ�. ������ ���� ���α��� �����Ѵ�.
class FieldAccess {
static int si;
String s;
private native void accessFields();
public static void main(String args[]) {
FieldAccess
c = new FieldAccess();
FieldAccess.si = 100;
c.s = "abc";
c.accessFields();
System.out.println("In Java:");
System.out.println(" FieldAccess.si = " + FieldAccess.si);
System.out.println(" c.s = \"" +
c.s + "\"");
}
static {
System.loadLibrary("MyImpOfFieldAccess");
}
}
�� ���α��� String�� s�� int�� si�� ���� ����ϰ�, ���ο� ������ �����ϴ� ������ �����Ѵ�.
native ����� ������ ����.
#include <stdio.h>
#include <jni.h>
#include "FieldAccess.h"
JNIEXPORT void JNICALL
Java_FieldAccess_accessFields(JNIEnv *env, jobject obj)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jfieldID fid;
jstring jstr;
const char *str;
jint si;
printf("In C:\n");
fid
= (*env)->GetStaticFieldID(env, cls, "si", "I");
if (fid == 0) {
return;
}
si = (*env)->GetStaticIntField(env, cls, fid);
printf("
FieldAccess.si = %d\n", si);
(*env)->SetStaticIntField(env,
cls, fid, 200);
fid = (*env)->GetFieldID(env,
cls, "s", "Ljava/lang/String;");
if (fid
== 0) {
return;
}
jstr = (*env)->GetObjectField(env,
obj, fid);
str = (*env)->GetStringUTFChars(env, jstr, 0);
printf(" c.s = \"%s\"\n", str);
(*env)->ReleaseStringUTFChars(env, jstr, str);
jstr = (*env)->NewStringUTF(env, "123");
(*env)->SetObjectField(env,
obj, fid, jstr);
}
Java ��� �����κ��� ���� ���ų� �����ϴ� ����� ������ ���� ����� ������ �ȴ�.
Calling Java Method �忡�� �����Ǿ��� Java VM Type Signatures�� �����Ѵ�.
JNI������ native ��������� ���� ������ ������ ��,
�̰��� �ڵ鸵�� �� �ִ� ����� �����Ѵ�. C�� ���� ���� ����� �������� �ʴ�
���� �����ϰ� �̿�� �� �ִ�.
������ ������ ���� ó���� �����ֱ� ���� Java ���α��̴�.
class CatchThrow {
private native void catchThrow()
throws IllegalArgumentException;
private void callback() throws
NullPointerException {
throw new NullPointerException("thrown
in CatchThrow.callback");
}
public static void
main(String args[]) {
CatchThrow c = new CatchThrow();
try {
c.catchThrow();
} catch (Exception e) {
System.out.println("In Java:\n " + e);
}
}
static {
System.loadLibrary("MyImpOfCatchThrow");
}
}
native �Լ��� catchThrow() �� try���� ������, ���ܻ�����
������ ��쿡 Exception �̺�Ʈ�� �Ѱ� �־�� �Ѵ�. callback() �Լ��� Exception
�̺�Ʈ�� ����Ű���� �Ǿ� �ִ�.
���� ������ �̿� �����ϴ� C ���α��̴�.
#include <jni.h>
#include "CatchThrow.h"
JNIEXPORT void JNICALL
Java_CatchThrow_catchThrow(JNIEnv
*env, jobject obj)
{
jclass cls = (*env)->GetObjectClass(env,
obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback",
"()V");
jthrowable exc;
if (mid == 0) {
return;
}
(*env)->CallVoidMethod(env,
obj, mid);
exc = (*env)->ExceptionOccurred(env);
if (exc) { /* We don't do much with the exception, except
that we print a
debug message using
ExceptionDescribe, clear it, and throw
a new exception. */
jclass newExcCls;
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
newExcCls
= (*env)->FindClass(env, "java/lang/IllegalArgumentException");
if (newExcCls == 0) { /* Unable to find the new exception
class, give up. */
return;
}
(*env)->ThrowNew(env, newExcCls, "thrown
from C code");
}
}
���ܻ����� ������ �� �ִ� �Լ��� ExceptionOccurred() �̴�. if(exc) {��} �� ������ ���ܻ����� ������ ��쿡 ó���� �� �����̴�. ExceptionDescribe() �Լ��� ȣ���ؼ� ����� ������ ����ϰ� �ǰ�, ExceptionClear() �� ȣ���ؼ� Ŭ�������ش�. �� ���Ŀ� ���ο� ���ܻ����� ����Ű���� �Ǿ� �ִµ�, IllegalArgumentException Ŭ������ ã�Ƽ� ThrowNew() �� ���� Exception �̺�Ʈ�� ����Ų��.
JNI�� �⺻������ ��ü�� ���� ���۷����� ������ ��, ����
���۷����� �����Ѵ�. �� ������� �������� ���, native �Լ��� ������ �ϰ� �Ǹ�,
�� ���۷����� �����Ǿ� ������. ���� �Ǹ�, ������ �ٽ� Java ���α����� ��
native �Լ��� ȣ���ؼ�, ��ü�� ���� ���۷����� �Ҵ�������� �ص�, �̹� �����Ǿ�
�����Ƿ�, ����� �� ���� �Ǿ� ������. �̰��� �����ϱ� ���ؼ� �۷ι� ���۷�����
�̿��ؾ� �Ѵ�.
���� ������ �ٷ� �տ� �忡�� ���Ҵ� ������ �����ؼ� �۷ι� ���۷�����
�Ҵ��ϴ� ���� �����ش�.
#include <stdio.h>
#include <jni.h>
#include "FieldAccess.h"
static jclass cls = 0;
/* static���� �����Ѵ�. */
static jfieldID fid;
JNIEXPORT
void JNICALL
Java_FieldAccess_accessFields(JNIEnv *env, jobject obj)
{
jstring jstr;
const char *str;
jint
si;
printf("In C:\n");
if (cls ==
0) {
jclass cls1 = (*env)->GetObjectClass(env, obj);
if (cls1 == 0) {
�� /* error */
}
cls = (*env)->NewGlobalRef(env, cls1); /* �̰��� �����Ѵ�. */
if (cls == 0) {
�� /* error */
}
fid = (*env)->GetStaticFieldID(env, cls, "si",
"I");
}
if (fid == 0) {
return;
}
si = (*env)->GetStaticIntField(env, cls,
fid);
printf(" FieldAccess.si = %d\n", si);
(*env)->SetStaticIntField(env, cls, fid, 200);
fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
if (fid == 0) {
return;
}
jstr = (*env)->GetObjectField(env, obj, fid);
str = (*env)->GetStringUTFChars(env,
jstr, 0);
printf(" c.s = \"%s\"\n",
str);
(*env)->ReleaseStringUTFChars(env, jstr, str);
jstr = (*env)->NewStringUTF(env, "123");
(*env)->SetObjectField(env, obj, fid, jstr);
}
�۷ι� ���۷����� Java Ŭ������ unload���� ���ϰ� �ϱ� ������, ��� ���� ID�� �״�� �����ְ� �ȴ�. ������, �� �̻��� �ʿ䰡 ���� ��쿡�� �ݵ�� DeleteGlobalRef() �Լ��� �̿��ؼ� ������ �־�� �Ѵ�. ���δ� DeleteLocalRef() �Լ��� �̿��ؼ� ���� ���۷����� ������ �־�� �� ��찡 �����. ���� ���� ������ ����.
���� ���κ��� Ȯ���� ����.
��
for(i = 0; i<len; i++) {
jstring jstr =
(*env)->GetObjectArrayElement(env, arr, i);
��
(*env)->DeleteLocalRef(env,
jstr);
}
��
Java�� ��Ƽ������ �ý����̴�. �̷��� �� ������, native �ҵ�� �������̾�� �Ѵ�. critcal ������ ������ ������ �� ��쿡�� ����ȭ�� �� �ִ� ����� ����Ǿ�� �Ѵ�.
�� ���� �����ؾ� �� ���� �ִ�.
����ȭ�� �� ���� ������� ����� �� �ִ�. ���� Java����, synchronized ������ ����ϴ� ����� �����غ� �� �ִ�.
synchronized(obj) {
��
}
native �ڵ忡���� MonitorEnter() �� MonitorExit() �� �̿��Ѵ�.
��
(*env)->MonitorEnter(env, obj);
/* synchronized
block */
(*env)->MonitorExit(env, obj)
��
Object.wait, Object.notify, Object.notifyAll�� ���� ����ȭ ����� �̿��� �� �ִ�. JNI������ ���������� ���������� ������, JNI �ҵ� ȣ�� ����� �̿��ؼ� �̸� ������ �� �ִ�.
C++�� �̿��ϸ� �� ��Ȯ�� �������̽��� JNI�� ����� �� �ִ�. ���� ���, C������ Ŭ������ ã�� ���ؼ� ������ ���� ����� ����ؾ� �Ѵ�.
jclass cls = env->FindClass(env, ��java/lang/String��);
��ſ�, C++������ ����ó�� �̿��� �� �ִ�.
jclass cls = env->FindClass(��java/lang/String��);
C++������ env ���ڰ� �����ȴ�. jni.h ���Ͽ����� C++������ jobject Ÿ�Կ� ���ؼ� ������ ���� ������ �ξ���.
class _jobject {};
class _jclass : public _jobject
{};
class _jthrowable : public _jobject {};
class _jstring : public
_jobject {};
... /* more on jarray */
typedef _jobject
*jobject;
typedef _jclass *jclass;
typedef _jthrowable *jthrowable;
typedef _jstring *jstring;
... /* more on jarray */
C++ �����Ϸ��� ������� ��쿡��, C�������� ������ Ÿ�� üũ�� �� �� �ִٴ� ������ ������ �ִ�. �� ���� �����ؾ� �� �����̶��, Ÿ�� ij������ �� �ʿ䰡 �ִ� ����̴�. ���� C���� ����ϴ� ȣ���� ���,
jstring jstr = (*env)->GetObjectArrayElement(env, arr, i);
C++������ ������ ���� ������� ȣ���� ���̴�.
jstring = (jstring)env->GetObjectArrayElement(arr, i);
�̴� GetObjectArrayElement() �� ���ϰ��� jobject�ε�, jsring�� �̰��� ����Ÿ���̱� ������, ij������ �� �־�� �Ѵ�.