Transcription of JNI: JAVA와 C++의 연동
1 JNI: JAVA C++ . : C++ for Java Programmers : Mark Allen Weiss : Frank Yoon : Windows XP, Java , Visual Studio , Vim JVM C C++ . JDK Java Native Interface .. , JVM C C++ .. JNI . (native method) , native .. 1. , . , JNI . 2.. JNI . (private).. , I/O, threading, networking .. 3. , C++ time-critical . JNI . JNI . 1. (Portability) . , . C++ , . (in the first place) . 2. (safety) .. C++ , , . C++ . 3..dll .so .. , .. 4.. JNI . 1. native . 2. JNI C++ . 3. C++ . 4. JVM .. JNI C++ C .. 1. C ? 2. C/C++ ? 3. C/C++ ? 4. C ? 5. ? 6. ? 7. C/C++ (exception) ? . ? .. class HelloNative {. native public static void hello();. static {. ( HelloNative );. }. }. class HelloNativeTest {.}
2 Public static void main(String[] args). {. ();. }. }. , HelloNative hello() .. HelloNativeTest . , JVM . () JVM .. , . UnsatisfiedLinkError . , C++ .. hello() C++ hello() . JNI , . , .. , javah . C++ .. javah HelloNative ( ) . /* DO NOT EDIT THIS FILE - it is machine generated */. #include < >. /* Header for class HelloNative */. #ifndef _Included_HelloNative #define _Included_HelloNative #ifdef __cplusplus extern "C" {. #endif /*. * Class: HelloNative * Method: hello * Signature: ()V. */. JNIEXPORT void JNICALL Java_HelloNative_hello (JNIEnv *, jclass);. #ifdef __cplusplus }. #endif #endif Java_HelloNative_hello . , .. JNIO bject JNIO bject .. jclass HelloNative.
3 Reflection API Class .. , C++ .. ( ) , javah .. #include <iostream>. using namespace std;. #include " ". JNIEXPORT void JNICALL Java_HelloNative_hello(JNIEnv *env, jclass cls). {. cout << "Hello world"<< endl;. }.. include , . (%JAVA_HOME% include ).. (Visual Studio ). cl -GX /GR -I%JAVA_HOME% include -I%JAVA_HOME% include win32 -LD . , linux solaris . g++ -c fPIC I$JAVA_HOME/include I$JAVA_HOME/include/linux g++ -shared o Standard Sun C++ , . CC G I$JAVA_HOME/include I$JAVA_HOME/include/solaris o JVM LD_LIBRARY_PATH .. PATH .. JNI Types , j . 8 . primitive c++ . jbyte, jshort, jint, jlong, jfloat, jdouble, jchar jboolean . jbyte, jint, jlong . %JAVA_HOME%/include/win32.
4 64 jlong int . typedef . C++ size_t jsize . String Object C++ jstring jobject . C++ JNI . const char* jstring , jstring char* .. Array C++ . jintArray . primitive jobjectArray .. jmethodId jfieldID , Reflection API Method Field . , .. , printDate . Date . printDate . Date . , getMonth, getDay getYear .. toString jstring C-style .. printDate Date . class Date {. public Date(int m, int d, int y). {month=m; day=d; year=y;}. Static {. ( Date );. }. native public void printDate();. public int getMonth(). { return month;}. public int getDay(). { return day;}. public int getYear(). { return year;}. public String toString(). { return month + / + day + / + year; }. private int month.}
5 Private int day;. private int year;. }. Date . class TestDate {. public static void main(String[] args). {. Date d = new Date(3, 1, 2006);. ();. }. }. A.. Date javah . /* DO NOT EDIT THIS FILE - it is machine generated */. #include < >. /* Header for class Date */. #ifndef _Included_Date #define _Included_Date #ifdef __cplusplus extern "C" {. #endif /*. * Class: Date * Method: printDate * Signature: ()V. */. JNIEXPORT void JNICALL Java_Date_printDate (JNIEnv *, jobject);. #ifdef __cplusplus }. #endif #endif printDate Java_Date_printDate jobject .. jobject . 1. jclass . 2. jclass jfieldID , .. 3. jfieldID jobject . jfieldID . , .. javap .. Date . javap s private Date.
6 #>javap -s -private Date Compiled from " ". class Date extends {. private int month; Signature: I. private int day; Signature: I. private int year; Signature: I. public Date(int, int, int); Signature: (III)V. public native void printDate(); Signature: ()V. public int getMonth(); Signature: ()I. public int getDay(); Signature: ()I. public int getYear(); Signature: ()I. public toString(); Signature: ()Ljava/lang/String;. static {}; Signature: ()V. }. int I, void V, . Ljava/lang/String . getYear ()I, printDate ()V, toString ()Ljava/lang/String .. String [Ljava/lang/String; . printDate . //printDate() . #include " ". #include <iostream>. using namespace std;. JNIEXPORT void JNICALL Java_Date_printDate(JNIEnv *env, jobject ths).]
7 {. jclass cls = env->GetObjectClass(ths);. jfieldID monthID = env->GetFieldID(cls, "month", "I");. jfieldID dayID = env->GetFieldID(cls, "day", "I");. jfieldID yearID = env->GetFieldID(cls, "year", "I");. jint m = env->GetIntField(ths, monthID);. jint d = env->GetIntField(ths, dayID);. jint y = env->GetIntField(ths, yearID);. cout << m << "/" << d << "/" << y << endl;. }. jclass ths , Date . JNIEnv . (environment member functions) .. JNI env . jclass , , GetFieldID . jfieldID . jfieldID .. 8 primitive GetXXXF ield . Object . GetObjectField . String GetObjectField jstring . SetXXXF ield Field . , GetFieldID GetStaticFieldID , jobject ths . jclass cls GetStaticXXXF ield.
8 SetStaticXXXF ield .. String GetObjectField , jobject jstring .. dynamic_cast jobject . reinterpret_cast . B.. , jclass .. , jmethodID . jclass .. GetXXXF ield .. , , XXX .. XXX CallXXXM ethod(jobject ths, jmethodID m, );. XXX CallStaticXXXM ethod(jclass cls, jmethodID m, );. printDate() . //printDate() . #include " ". #include <iostream>. using namespace std;. JNIEXPORT void JNICALL Java_Date_printDate(JNIEnv *env, jobject ths). {. jclass cls = env->GetObjectClass(ths);. jmethodID getMonthID, getDayID, getYearID;. getMonthID = env->GetMethodID(cls, "getMonth", "()I");. getDayID = env->GetMethodID(cls, "getDay", "()I");. getYearID = env->GetMethodID(cls, "getYear", "()I").}
9 Jint m = env->CallIntMethod(ths, getMonthID);. jint d = env->CallIntMethod(ths, getDayID);. jint y = env->CallIntMethod(ths, getYearID);. cout << m << "/" << d << "/" << y << endl;. }. CallXXXM ethod (dynamic dispatch) .. XXX CallNonvirtualXXXM ethod(jobject ths, jmethodID m, );.. C.. NewObject . jclass, jmethodID .. jmethodID <init> . Date .. jclass dateClass = env->FindClass( Date );. jmethodID ctor = env->GetMethodId(dateClass, <init> , (III)V );. jobject d1 = env->NewObject(dateClass, ctor, 1, 1, 2006);.. jstring jintArray C++ .. environment JNI primitive . A.. jstring const char * environment GetStringUTFChar .. GetStringUTFChar jstring jboolean . NULL , Boolean char * true , false.
10 , NULL . GetStringUTFC hars const char * , . ReleaseStringUTFC hars . printDate() . JVM toString() . //printDate() . #include " ". #include <iostream>. using namespace std;. JNIEXPORT void JNICALL Java_Date_printDate(JNIEnv *env, jobject ths). {. jclass cls = env->GetObjectClass(ths);. jmethodID toStringID = env->GetMethodID(cls, "toString", "()Ljava/lang/String;");. jstring str = (jstring) env->CallObjectMethod(ths, toStringID);. const char *c_ret = env->GetStringUTFC hars(str, NULL);. cout << "(calling toString) " << c_ret << endl;. env->ReleaseStringUTFC hars(str, c_ret);. }.. NewStringUTF jstring . StringAdd . add . // . JNIEXPORT jstring JNICALL Java_StringAdd_add(JNIEnv *env, jclass cls, jstring a, jstring b).