00001
00013 #include "jnilib.h"
00014
00015 #include <stdarg.h>
00016
00017 #ifdef __cplusplus
00018 extern "C" {
00019 #endif
00020
00022 #define CLS_JNILIB "at/fhv/sgr/jnilib/JNILIB"
00023
00025 #define CLASSPATH_PARAM "-Djava.class.path="
00026
00028 #define DEFAULT_CLASSPATH "."
00029
00030 #ifdef __cplusplus
00031 #define createJvm createJvmCPP
00033 #define JNILIB_PARAM_JVM
00034 #define JNILIB_PARAM_END_JVM
00035 #define JNILIB_JAVAVM (jvm->jvm.jvm)
00036 #define JNILIB_PARAM_JAVAVM
00038 #define JNILIB_GETJAVAVM getJavaVM()
00039 #define JNILIB_GETJAVAVM_PARAM
00041 #define JNILIB_ENV getJNIEnv()
00042 #define JNILIB_PARAM_ENV
00043 #define JNILIB_PARAM_END_ENV
00044 #else
00045 #define createJvm createJvmC
00047 #define JNILIB_PARAM_JVM jvm,
00048 #define JNILIB_PARAM_END_JVM jvm
00049 #define JNILIB_JAVAVM (*(jvm->jvm.jvm))
00050 #define JNILIB_PARAM_JAVAVM jvm->jvm.jvm
00052 #define JNILIB_GETJAVAVM (*getJavaVM())
00053 #define JNILIB_GETJAVAVM_PARAM getJavaVM(),
00055 #define JNILIB_ENV (*(getJNIEnv()))
00056 #define JNILIB_PARAM_ENV getJNIEnv(),
00057 #define JNILIB_PARAM_END_ENV getJNIEnv()
00058 #endif
00059
00061 JavaVM* javavm = NULL;
00062
00063 void createJvmC(Jvm_* jvm);
00064 void createJvmCPP(JvmCPP_* jvm);
00065
00066 jint startJvm(Jvm* jvm);
00067 void setJvmClasspath(Jvm* jvm, const char* cp);
00068
00075 void initJvm(Jvm* jvm, const char* classpath) {
00076 createJvm(jvm);
00077 setJvmClasspath(jvm, classpath);
00078 startJvm(jvm);
00079 }
00080
00086 JavaVM* getJavaVM() {
00087
00088 if (javavm == NULL) {
00089 fprintf(stdout, "Java Virtual Machine not created!\nError in file %s at line #%d!\nThe Programm wil terminate!\n", __FILE__, __LINE__);
00090 abort();
00091 }
00092 return javavm;
00093 }
00094
00104 JNIEnv* getJNIEnv() {
00105 JNIEnv* env;
00106
00107 if (javavm == NULL) {
00108 fprintf(stdout, "Java Virtual Machine not created!\nError in file %s at line #%d!\nThe Programm wil terminate!\n", __FILE__, __LINE__);
00109 abort();
00110 }
00111 JNILIB_GETJAVAVM->AttachCurrentThread(JNILIB_GETJAVAVM_PARAM (void **)&env, NULL);
00112 return env;
00113 }
00114
00121 void setJvmClasspath(Jvm* jvm, const char* cp) {
00122 jvm->jvm.classpath = cp;
00123 }
00124
00132 jint startJvm(Jvm* jvm) {
00133 int ret = 0;
00134 JavaVMOption options[3];
00135 char classpath[1024];
00136
00137
00138
00139 if (javavm != NULL) {
00140 fprintf(stdout, "Java Virtual Machine already created!\nError in file %s at line #%d!\nThe Programm wil terminate!\n", __FILE__, __LINE__);
00141 abort();
00142 }
00143
00144 jvm->jvm.vm_args.version = JNI_VERSION_1_4;
00145
00146 #ifdef DEBUG
00147 jvm->jvm.vm_args.nOptions = 2;
00148 #else
00149 jvm->jvm.vm_args.nOptions = 1;
00150 #endif
00151
00152 sprintf(classpath, "%s%s", CLASSPATH_PARAM, jvm->jvm.classpath);
00153
00154 options[0].optionString = classpath;
00155 options[0].extraInfo = (void*)"";
00156
00157
00158 options[1].optionString = "-Xcheck:jni";
00159 options[1].extraInfo = (void*)"";
00160 options[2].optionString = "-verbose:jni";
00161 options[2].extraInfo = (void*)"";
00162
00163 jvm->jvm.vm_args.options = options;
00164 jvm->jvm.vm_args.ignoreUnrecognized = JNI_TRUE;
00165
00166
00167
00168
00169
00170
00171
00172 if ((ret = JNI_CreateJavaVM(&(jvm->jvm.jvm), (void**)&(jvm->jvm.env), &(jvm->jvm.vm_args))) < 0) {
00173 fprintf(stderr, "Can't create Java VM\nReturn Code: %d\n", ret);
00174 return ret;
00175 }
00176
00177 javavm = jvm->jvm.jvm;
00178
00179 return ret;
00180 }
00181
00191 jint destroyJvm(Jvm* jvm) {
00192 return JNILIB_JAVAVM->DestroyJavaVM(JNILIB_PARAM_JAVAVM);
00193 }
00194
00200 void createJvm_(Jvm_* jvm) {
00201 jvm->destroyJvm = &destroyJvm;
00202
00203 setJvmClasspath((Jvm*)jvm, DEFAULT_CLASSPATH);
00204 }
00205
00212 void createJvmCPP(JvmCPP_* jvm) {
00213 jvm->functions = (Jvm_*)malloc(sizeof(Jvm_));
00214 createJvm_(jvm->functions);
00215 }
00216
00223 void createJvmC(Jvm_* jvm) {
00224 createJvm_(jvm);
00225 }
00226
00236 jclass findClass(const char* strclass) {
00237 jclass ret;
00238 ret = JNILIB_ENV->FindClass(JNILIB_PARAM_ENV strclass);
00239
00240 exception();
00241
00242 if (ret == NULL) {
00243 fprintf(stderr, "Could not find Class: %s\n", strclass);
00244 } else {
00245 ret = (jclass)createGlobalReference(ret);
00246 }
00247
00248 return ret;
00249 }
00250
00260 jclass getObjectClass(jobject obj) {
00261 jclass ret;
00262 ret = JNILIB_ENV->GetObjectClass(JNILIB_PARAM_ENV obj);
00263 return (jclass)createGlobalReference(ret);
00264 }
00265
00281 jmethodID findStaticMethod(jclass cls, const char* method, const char* signature) {
00282 jmethodID ret;
00283 ret = JNILIB_ENV->GetStaticMethodID(JNILIB_PARAM_ENV cls, method, signature);
00284 if (ret == NULL) {
00285 fprintf(stderr, "Could not find static Method: %s\n", method);
00286 }
00287 return ret;
00288 }
00289
00299 jfieldID findStaticField(jclass cls, const char* field, const char* signature) {
00300 jfieldID ret;
00301 ret = JNILIB_ENV->GetStaticFieldID(JNILIB_PARAM_ENV cls, field, signature);
00302 if (ret == NULL) {
00303 fprintf(stderr, "Could not find static Field: %s\n", field);
00304 }
00305 return ret;
00306 }
00307
00319 jmethodID findMethod(jclass cls, const char* method, const char* signature) {
00320 jmethodID ret;
00321 ret = JNILIB_ENV->GetMethodID(JNILIB_PARAM_ENV cls, method, signature);
00322 if (ret == NULL) {
00323 fprintf(stderr, "Could not find Method: %s\n", method);
00324 }
00325 return ret;
00326 }
00327
00337 jint registerNatives(jclass cls, const JNINativeMethod* nm, jint nMethods) {
00338 jint ret;
00339 ret = JNILIB_ENV->RegisterNatives(JNILIB_PARAM_ENV cls, nm, nMethods);
00340 if (ret != 0) {
00341 fprintf(stderr, "Could not register Method: %s\n", nm->name);
00342 }
00343 return ret;
00344 }
00345
00351 void deleteLocalReference(jobject obj) {
00352 JNILIB_ENV->DeleteLocalRef(JNILIB_PARAM_ENV obj);
00353 }
00354
00360 void deleteGlobalReference(jobject obj) {
00361 JNILIB_ENV->DeleteGlobalRef(JNILIB_PARAM_ENV obj);
00362 }
00363
00371 jobject createGlobalReference(jobject obj) {
00372 jobject ret;
00373 ret = JNILIB_ENV->NewGlobalRef(JNILIB_PARAM_ENV obj);
00374 deleteLocalReference(obj);
00375 return ret;
00376 }
00377
00386 jboolean isSameObject(jobject obj1, jobject obj2) {
00387 return JNILIB_ENV->IsSameObject(JNILIB_PARAM_ENV obj1, obj2);
00388 }
00389
00395 jboolean exception() {
00396 jthrowable exc;
00397
00398 exc = JNILIB_ENV->ExceptionOccurred(JNILIB_PARAM_END_ENV);
00399 if (exc) {
00400
00401
00402 JNILIB_ENV->ExceptionDescribe(JNILIB_PARAM_END_ENV);
00403 JNILIB_ENV->ExceptionClear(JNILIB_PARAM_END_ENV);
00404 deleteLocalReference(exc);
00405 }
00406 return (exc != NULL);
00407 }
00408
00418 jstring createJString(const char* str) {
00419 static jclass clsstring = NULL;
00420 static jmethodID mid = NULL;
00421 jstring result = NULL;
00422 jbyteArray bytes = 0;
00423 jsize len;
00424
00425 if (clsstring == NULL) {
00426 clsstring = findClass("java/lang/String");
00427 mid = findMethod(clsstring, "<init>", "([B)V");
00428 }
00429
00430 if (JNILIB_ENV->EnsureLocalCapacity(JNILIB_PARAM_ENV 2) < 0) {
00431 return NULL;
00432 }
00433
00434 len = (jsize)strlen(str);
00435 bytes = JNILIB_ENV->NewByteArray(JNILIB_PARAM_ENV len);
00436 if (bytes != NULL) {
00437 JNILIB_ENV->SetByteArrayRegion(JNILIB_PARAM_ENV bytes, 0, len, (jbyte *)str);
00438 result = (jstring) newObject(clsstring, mid, bytes);
00439 deleteLocalReference(bytes);
00440 }
00441 return result;
00442 }
00443
00455 char* convertJString(jstring jstr) {
00456 static jclass clsstring = NULL;
00457 static jmethodID mid = NULL;
00458 jbyteArray bytes = NULL;
00459 jthrowable exc;
00460 char *result = NULL;
00461
00462 if (jstr == NULL) {
00463 return "";
00464 }
00465
00466 if (clsstring == NULL) {
00467 clsstring = findClass("java/lang/String");
00468 mid = findMethod(clsstring, "getBytes", "()[B");
00469 }
00470
00471 if (JNILIB_ENV->EnsureLocalCapacity(JNILIB_PARAM_ENV 2) < 0) {
00472 return "OUT OF MEMORY";
00473 }
00474 bytes = (jbyteArray) callObjectMethod(jstr, mid);
00475 exc = JNILIB_ENV->ExceptionOccurred(JNILIB_PARAM_END_ENV);
00476 if (!exc) {
00477 jint len = JNILIB_ENV->GetArrayLength(JNILIB_PARAM_ENV bytes);
00478 result = (char *)malloc(len + 1);
00479 if (result == 0) {
00480 throwByName("java/lang/OutOfMemoryError", 0);
00481 } else {
00482 JNILIB_ENV->GetByteArrayRegion(JNILIB_PARAM_ENV bytes, 0, len, (jbyte *)result);
00483 result[len] = 0;
00484 }
00485 }
00486 deleteLocalReference(exc);
00487 deleteLocalReference(bytes);
00488 return result;
00489 }
00490
00497 void throwByName(const char *name, const char *msg) {
00498 jclass cls = findClass((char*)name);
00499
00500 if (cls != NULL) {
00501 JNILIB_ENV->ThrowNew(JNILIB_PARAM_ENV cls, msg);
00502 }
00503
00504 deleteLocalReference(cls);
00505 }
00506
00512 void jnisleep(jint ms) {
00513 static jclass cls = NULL;
00514 static jmethodID mjnisleep = NULL;
00515
00516 if (cls == NULL) {
00517 cls = findClass(CLS_JNILIB);
00518 mjnisleep = findStaticMethod(cls, "sleep", "(I)V");
00519 }
00520 callStaticVoidMethod(cls, mjnisleep, ms);
00521 }
00522
00532 jobject newObject(jclass cls, jmethodID mid, ...) {
00533 jobject ret;
00534 va_list args;
00535
00536 va_start(args, mid);
00537
00538 ret = JNILIB_ENV->NewObjectV(JNILIB_PARAM_ENV cls, mid, args);
00539
00540 ret = createGlobalReference(ret);
00541
00542 va_end(args);
00543 return ret;
00544 }
00545
00555 jobject newObjectBySignature(jclass cls, const char* signature, ...) {
00556 jobject ret;
00557 va_list args;
00558 jmethodID mid;
00559
00560 va_start(args, signature);
00561 mid = findMethod(cls, "<init>", signature);
00562
00563 ret = JNILIB_ENV->NewObjectV(JNILIB_PARAM_ENV cls, mid, args);
00564
00565 ret = createGlobalReference(ret);
00566
00567 va_end(args);
00568 return ret;
00569 }
00570
00578 void callStaticVoidMethod(jclass cls, jmethodID mid, ...) {
00579 va_list args;
00580
00581 va_start(args, mid);
00582
00583 JNILIB_ENV->CallStaticVoidMethodV(JNILIB_PARAM_ENV cls, mid, args);
00584
00585 va_end(args);
00586 }
00587
00595 void callVoidMethod(jobject obj, jmethodID mid, ...) {
00596 va_list args;
00597
00598 va_start(args, mid);
00599
00600 JNILIB_ENV->CallVoidMethodV(JNILIB_PARAM_ENV obj, mid, args);
00601
00602 va_end(args);
00603 }
00604
00614 jboolean callBooleanMethod(jobject obj, jmethodID mid, ...) {
00615 jboolean ret;
00616 va_list args;
00617
00618 va_start(args, mid);
00619
00620 ret = JNILIB_ENV->CallBooleanMethodV(JNILIB_PARAM_ENV obj, mid, args);
00621
00622 va_end(args);
00623 return ret;
00624 }
00625
00635 jbyte callByteMethod(jobject obj, jmethodID mid, ...) {
00636 jbyte ret;
00637 va_list args;
00638
00639 va_start(args, mid);
00640
00641 ret = JNILIB_ENV->CallByteMethodV(JNILIB_PARAM_ENV obj, mid, args);
00642
00643 va_end(args);
00644 return ret;
00645 }
00646
00656 jchar callCharMethod(jobject obj, jmethodID mid, ...) {
00657 jchar ret;
00658 va_list args;
00659
00660 va_start(args, mid);
00661
00662 ret = JNILIB_ENV->CallCharMethodV(JNILIB_PARAM_ENV obj, mid, args);
00663
00664 va_end(args);
00665 return ret;
00666 }
00667
00677 jshort callShortMethod(jobject obj, jmethodID mid, ...) {
00678 jshort ret;
00679 va_list args;
00680
00681 va_start(args, mid);
00682
00683 ret = JNILIB_ENV->CallShortMethodV(JNILIB_PARAM_ENV obj, mid, args);
00684
00685 va_end(args);
00686 return ret;
00687 }
00688
00698 jint callStaticIntMethod(jclass cls, jmethodID mid, ...) {
00699 jint ret;
00700 va_list args;
00701
00702 va_start(args, mid);
00703
00704 ret = JNILIB_ENV->CallStaticIntMethodV(JNILIB_PARAM_ENV cls, mid, args);
00705
00706 va_end(args);
00707 return ret;
00708 }
00709
00719 jint callIntMethod(jobject obj, jmethodID mid, ...) {
00720 jint ret;
00721 va_list args;
00722
00723 va_start(args, mid);
00724
00725 ret = JNILIB_ENV->CallIntMethodV(JNILIB_PARAM_ENV obj, mid, args);
00726
00727 va_end(args);
00728 return ret;
00729 }
00730
00740 jlong callLongMethod(jobject obj, jmethodID mid, ...) {
00741 jlong ret;
00742 va_list args;
00743
00744 va_start(args, mid);
00745
00746 ret = JNILIB_ENV->CallLongMethodV(JNILIB_PARAM_ENV obj, mid, args);
00747
00748 va_end(args);
00749 return ret;
00750 }
00751
00761 jfloat callFloatMethod(jobject obj, jmethodID mid, ...) {
00762 jfloat ret;
00763 va_list args;
00764
00765 va_start(args, mid);
00766
00767 ret = JNILIB_ENV->CallFloatMethodV(JNILIB_PARAM_ENV obj, mid, args);
00768
00769 va_end(args);
00770 return ret;
00771 }
00772
00782 jdouble callDoubleMethod(jobject obj, jmethodID mid, ...) {
00783 jdouble ret;
00784 va_list args;
00785
00786 va_start(args, mid);
00787
00788 ret = JNILIB_ENV->CallDoubleMethodV(JNILIB_PARAM_ENV obj, mid, args);
00789
00790 va_end(args);
00791 return ret;
00792 }
00793
00803 jobject callStaticObjectMethod(jclass cls, jmethodID mid, ...) {
00804 jobject ret;
00805 va_list args;
00806
00807 va_start(args, mid);
00808
00809 ret = JNILIB_ENV->CallStaticObjectMethodV(JNILIB_PARAM_ENV cls, mid, args);
00810
00811 va_end(args);
00812 return ret;
00813 }
00814
00824 jobject callObjectMethod(jobject obj, jmethodID mid, ...) {
00825 jobject ret;
00826 va_list args;
00827
00828 va_start(args, mid);
00829
00830 ret = JNILIB_ENV->CallObjectMethodV(JNILIB_PARAM_ENV obj, mid, args);
00831
00832 va_end(args);
00833 return ret;
00834 }
00835
00844 void callVoidMethodByName(jobject obj, const char* method, const char* signature, ...) {
00845 va_list args;
00846 jclass cls;
00847 jmethodID mid;
00848
00849 va_start(args, signature);
00850 cls = getObjectClass(obj);
00851 mid = findMethod(cls, method, signature);
00852
00853 JNILIB_ENV->CallVoidMethodV(JNILIB_PARAM_ENV obj, mid, args);
00854
00855 deleteGlobalReference(cls);
00856
00857 va_end(args);
00858 }
00859
00870 jboolean callBooleanMethodByName(jobject obj, const char* method, const char* signature, ...) {
00871 jboolean ret;
00872 va_list args;
00873 jclass cls;
00874 jmethodID mid;
00875
00876 va_start(args, signature);
00877 cls = getObjectClass(obj);
00878 mid = findMethod(cls, method, signature);
00879
00880 ret = JNILIB_ENV->CallBooleanMethodV(JNILIB_PARAM_ENV obj, mid, args);
00881
00882 deleteGlobalReference(cls);
00883
00884 va_end(args);
00885 return ret;
00886 }
00887
00898 jbyte callByteMethodByName(jobject obj, const char* method, const char* signature, ...) {
00899 jbyte ret;
00900 va_list args;
00901 jclass cls;
00902 jmethodID mid;
00903
00904 va_start(args, signature);
00905 cls = getObjectClass(obj);
00906 mid = findMethod(cls, method, signature);
00907
00908 ret = JNILIB_ENV->CallByteMethodV(JNILIB_PARAM_ENV obj, mid, args);
00909
00910 deleteGlobalReference(cls);
00911
00912 va_end(args);
00913 return ret;
00914 }
00915
00926 jchar callCharMethodByName(jobject obj, const char* method, const char* signature, ...) {
00927 jchar ret;
00928 va_list args;
00929 jclass cls;
00930 jmethodID mid;
00931
00932 va_start(args, signature);
00933 cls = getObjectClass(obj);
00934 mid = findMethod(cls, method, signature);
00935
00936 ret = JNILIB_ENV->CallCharMethodV(JNILIB_PARAM_ENV obj, mid, args);
00937
00938 deleteGlobalReference(cls);
00939
00940 va_end(args);
00941 return ret;
00942 }
00943
00954 jshort callShortMethodByName(jobject obj, const char* method, const char* signature, ...) {
00955 jshort ret;
00956 va_list args;
00957 jclass cls;
00958 jmethodID mid;
00959
00960 va_start(args, signature);
00961 cls = getObjectClass(obj);
00962 mid = findMethod(cls, method, signature);
00963
00964 ret = JNILIB_ENV->CallShortMethodV(JNILIB_PARAM_ENV obj, mid, args);
00965
00966 deleteGlobalReference(cls);
00967
00968 va_end(args);
00969 return ret;
00970 }
00971
00982 jint callIntMethodByName(jobject obj, const char* method, const char* signature, ...) {
00983 jint ret;
00984 va_list args;
00985 jclass cls;
00986 jmethodID mid;
00987
00988 va_start(args, signature);
00989 cls = getObjectClass(obj);
00990 mid = findMethod(cls, method, signature);
00991
00992 ret = JNILIB_ENV->CallIntMethodV(JNILIB_PARAM_ENV obj, mid, args);
00993
00994 deleteGlobalReference(cls);
00995
00996 va_end(args);
00997 return ret;
00998 }
00999
01010 jlong callLongMethodByName(jobject obj, const char* method, const char* signature, ...) {
01011 jlong ret;
01012 va_list args;
01013 jclass cls;
01014 jmethodID mid;
01015
01016 va_start(args, signature);
01017 cls = getObjectClass(obj);
01018 mid = findMethod(cls, method, signature);
01019
01020 ret = JNILIB_ENV->CallLongMethodV(JNILIB_PARAM_ENV obj, mid, args);
01021
01022 deleteGlobalReference(cls);
01023
01024 va_end(args);
01025 return ret;
01026 }
01027
01038 jfloat callFloatMethodByName(jobject obj, const char* method, const char* signature, ...) {
01039 jfloat ret;
01040 va_list args;
01041 jclass cls;
01042 jmethodID mid;
01043
01044 va_start(args, signature);
01045 cls = getObjectClass(obj);
01046 mid = findMethod(cls, method, signature);
01047
01048 ret = JNILIB_ENV->CallFloatMethodV(JNILIB_PARAM_ENV obj, mid, args);
01049
01050 deleteGlobalReference(cls);
01051
01052 va_end(args);
01053 return ret;
01054 }
01055
01066 jdouble callDoubleMethodByName(jobject obj, const char* method, const char* signature, ...) {
01067 jdouble ret;
01068 va_list args;
01069 jclass cls;
01070 jmethodID mid;
01071
01072 va_start(args, signature);
01073 cls = getObjectClass(obj);
01074 mid = findMethod(cls, method, signature);
01075
01076 ret = JNILIB_ENV->CallDoubleMethodV(JNILIB_PARAM_ENV obj, mid, args);
01077
01078 deleteGlobalReference(cls);
01079
01080 va_end(args);
01081 return ret;
01082 }
01083
01094 jobject callObjectMethodByName(jobject obj, const char* method, const char* signature, ...) {
01095 jobject ret;
01096 va_list args;
01097 jclass cls;
01098 jmethodID mid;
01099 cls = getObjectClass(obj);
01100 mid = findMethod(cls, method, signature);
01101
01102 va_start(args, signature);
01103
01104 ret = JNILIB_ENV->CallObjectMethodV(JNILIB_PARAM_ENV obj, mid, args);
01105
01106 deleteGlobalReference(cls);
01107
01108 va_end(args);
01109 return ret;
01110 }
01111
01120 jint getStaticIntFieldByName(const char* strclass, const char* strfield) {
01121 jint ret;
01122 jclass cls;
01123 jfieldID fid;
01124
01125 cls = findClass(strclass);
01126 fid = findStaticField(cls, strfield, "I");
01127
01128 ret = JNILIB_ENV->GetStaticIntField(JNILIB_PARAM_ENV cls, fid);
01129
01130 deleteGlobalReference(cls);
01131
01132 return ret;
01133 }
01134
01144 jobject getStaticObjectFieldByName(const char* strclass, const char* strfield, const char* signature) {
01145 jobject ret;
01146 jclass cls;
01147 jfieldID fid;
01148
01149 cls = findClass(strclass);
01150 fid = findStaticField(cls, strfield, signature);
01151
01152 ret = JNILIB_ENV->GetStaticObjectField(JNILIB_PARAM_ENV cls, fid);
01153
01154 deleteGlobalReference(cls);
01155
01156 return ret;
01157 }
01158
01159 #ifdef __cplusplus
01160 }
01161 #endif
01162
01163