�� �忡���� native ���α���, JVM�� �����Ű�� ����� ���ؼ� �����Ѵ�. �̰��� ������ ����� ���ϰ� �ִ�. ���� ���, Java ���ø��� �����ϴ� �� �������� �����Ѵٰ� �������� ��, JVM�� ������Ѽ� ������ �� �ִ�.
�� �κп����� JVM�� native ���̺귯���κ��� native ���α����� �ε��ϴ� ����� ���ؼ� �����Ѵ�. JVM�� �ʱ�ȭ�ؼ� Java �ҵ带 ȣ���ϴ� ����� ���ؼ��� �����ȴ�. Invocation API�� ���ؼ�, native �����带 �����ϰ� �ִ� JVM�� �ٿ��� ��ü������ Java ������� �����ϰ� �� �� �ִ�. ���� �� ����� Win32������ �����ǰ� �ִ�.
JNI�� �̿��ؼ�, native�� ���� ���̺귯���� native ���α��� ������Ѽ� �ű JVM�� �����ų �� �ִ�.
JNI�� Invocation API�� �����ϴµ�, �̰�����, ��java�� ���������� ������� �ʰ�, C���� �ٷ� Java ���α��� ������ �� �ֵ��� �� �� �ִ�.
�� ������ �����ϱ� ���� ������ ������ ������ �Ѵ�.
public class Prog {
public static void main(String[] args) {
System.out.println("Hello
World" + args[0]);
}
}
���� Java ���α��� ���� C ���α��� �����ϰ� �� JVM�� ���� ������ �� ���̴�.
#include <jni.h>
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif
#define USER_CLASSPATH "." /* where Prog.class is */
main() {
JNIEnv *env;
JavaVM *jvm;
JDK1_1InitArgs vm_args;
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
char classpath[1024];
/* IMPORTANT: specify vm_args version # if you use JDK1.1.2
and beyond */
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the end of default system
class path */
sprintf(classpath, "%s%c%s",
vm_args.classpath,
PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm,&env,&vm_args);
if (res < 0) {
fprintf(stderr, "Can't create
Java VM\n");
exit(1);
}
cls = (*env)->FindClass(env, "Prog");
if (cls == 0) {
fprintf(stderr, "Can't find
Prog class\n");
exit(1);
}
mid = (*env)->GetStaticMethodID(env, cls, "main",
"([Ljava/lang/String;)V");
if (mid == 0) {
fprintf(stderr, "Can't find
Prog.main\n");
exit(1);
}
jstr = (*env)->NewStringUTF(env, " from C!");
if (jstr == 0) {
fprintf(stderr, "Out of
memory\n");
exit(1);
}
args = (*env)->NewObjectArray(env, 1,
(*env)->FindClass(env, "java/lang/String"), jstr);
if (args == 0) {
fprintf(stderr, "Out of
memory\n");
exit(1);
}
(*env)->CallStaticVoidMethod(env, cls, mid, args);
(*jvm)->DestroyJavaVM(jvm);
}
JNI_GetDefaultJavaVMInitArgs() �Լ��� �̿��ؼ�, JVM�� �ʱ�ȭ�ϱ� ���� ���ڵ��� ���� �Ѵ�. �� ��, JNI_CreateJavaVM() �� �̿��ؼ� VM�� �ε��ϰ� �ʱ�ȭ�Ѵ�. �� �Լ��� ������ ���� ���ڸ� �ʿ�� �Ѵ�.
JVM�� �����Ű�� �Ͱ� native �ҵ带 �����ϴ� �Ͱ���
�����ϴ�. ������, ���̰� ���� ���̶�� ���� ������ �������� �ʴ� ���̴�. ���Ƿ�,
���� ���۷����������� DestroyJavaVM() �� ����DZ� ���������� �������� �ʴ´�.
VM�� �ε�� ��, �Ϲ����� JNI �Լ��� ȣ���ؼ� Java ���α��� �����ؼ� ������
�� ��, ����������, DestroyJavaVM() ���� VM�� �����Ѵ�.
�������� ������ ���� ������� �� �� �ִ�. ���� Solaris�� ���,
cc -I<where jni.h is> -L<where libjava.so is> -ljava invoke.c
Win32�� VC++ 4.0�� ��쿡��
cl -I<where jni.h is> -MT invoke.c -link<where javai.lib is>\javai.lib
native �����带 JVM�� ���� �� �ִ�. ����� Win32ȯ�濡���� ������ �ǰ�, �����δ� Solaris���� �������� ������ ���δ�.
���� ������ Win32���̸�, �տ��� ����ߴ� ������ ������� ���̱� ���ؼ� ������ ������ ���̴�.
/* Note: This program only works on Win32.
*/
#include <windows.h>
#include <jni.h>
JavaVM *jvm;
void thread_fun(void *arg)
{
jint res;
jclass cls;
jmethodID mid;
jstring jstr;
jobjectArray args;
JNIEnv *env;
char buf[100];
int threadNum = (int)arg;
/* Pass NULL as the third argument */
res = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
if (res < 0) {
fprintf(stderr, "Thread %d: attach
failed\n", threadNum);
return;
}
cls = (*env)->FindClass(env, "Prog");
if (cls == 0) {
fprintf(stderr, "Thread
%d: Can't find Prog class\n", threadNum);
goto detach;
}
mid = (*env)->GetStaticMethodID(env, cls, "main",
"([Ljava/lang/String;)V");
if (mid == 0) {
fprintf(stderr, "Thread
%d: Can't find Prog.main\n", threadNum);
goto detach;
}
sprintf(buf, " from Thread %d", threadNum);
jstr = (*env)->NewStringUTF(env, buf);
if (jstr == 0) {
fprintf(stderr, "Thread
%d: Out of memory\n", threadNum);
goto detach;
}
args = (*env)->NewObjectArray(env, 1,
(*env)->FindClass(env, "java/lang/String"), jstr);
if (args == 0) {
fprintf(stderr, "Thread
%d: Out of memory\n", threadNum);
goto detach;
}
(*env)->CallStaticVoidMethod(env, cls, mid, args);
detach:
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
(*jvm)->DetachCurrentThread(jvm);
}
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif
#define USER_CLASSPATH "." /* where Prog.class is */
main() {
JNIEnv *env;
JDK1_1InitArgs vm_args;
int i;
jint res;
char classpath[1024];
/* IMPORTANT: specify vm_args version # if you use JDK1.1.2
and beyond */
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the end of default system
class path */
sprintf(classpath, "%s%c%s",
vm_args.classpath,
PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, &env, &vm_args);
if (res < 0) {
fprintf(stderr, "Can't create
Java VM\n");
exit(1);
}
for (i=0; i<5; i++)
/* We pass the thread number
as the argument to every thread */
_beginthread(thread_fun,0,(void
*)i);
Sleep(5000); /* wait for threads to finish */
(*jvm)->DestroyJavaVM(jvm);
}
ũ�� ���� ������ ����. ����, �����带 ����ϱ� ���ؼ� Win32���� �����ϴ� �ҵ带 ����ؼ� �����带 ����������, ������ ���� �ȿ�, AttachCurrentThread() �� ȣ���ϴ� �Ϳ� ���ؼ� ���� ���� ���� �Ѵ�. �̰��� ������ν� �ٵ��� ���ִ� ���̸�, ����° ���ڴ� ������ �Ǿ� �־, NULL�� ������ ���ָ� �ȴ�.
DetachCurrentThread() �� ȣ���ϰ� �Ǹ� ���� �����忡 �ҼӵǾ� �ִ� ��� ���� ���۷����� �����ϰ� �ȴ�.
�� ���� JNI�� invocation API�� ���� ���� ������ �����Ѵ�.