📄 jni.xs
字号:
/* * Copyright 1997, O'Reilly & Associate, Inc. * * This package may be copied under the same terms as Perl itself. */#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include <stdio.h>#include <jni.h>#ifndef PERL_VERSION# include <patchlevel.h># define PERL_REVISION 5# define PERL_VERSION PATCHLEVEL# define PERL_SUBVERSION SUBVERSION#endif#if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75))# define PL_na na# define PL_sv_no sv_no# define PL_sv_undef sv_undef# define PL_dowarn dowarn#endif#ifndef newSVpvn# define newSVpvn(a,b) newSVpv(a,b)#endif#ifndef pTHX# define pTHX void# define pTHX_# define aTHX# define aTHX_# define dTHX extern int JNI___notused#endif#ifndef WIN32# include <dlfcn.h>#endif#ifdef EMBEDDEDPERLextern JNIEnv* jplcurenv;extern int jpldebug;#elseJNIEnv* jplcurenv;int jpldebug = 1;#endif#define SysRet jint#ifdef WIN32static void JNICALL call_my_exit(jint status){ my_exit(status);}#elsestatic void call_my_exit(jint status){ my_exit(status);}#endifjvalue*makeargs(char *sig, SV** svp, int items){ jvalue* jv = (jvalue*)safemalloc(sizeof(jvalue) * items); int ix = 0; char *s = sig; JNIEnv* env = jplcurenv; char *start; STRLEN n_a; if (jpldebug) fprintf(stderr, "sig = %s, items = %d\n", sig, items); if (*s++ != '(') goto cleanup; while (items--) { SV *sv = *svp++; start = s; switch (*s++) { case 'Z': jv[ix++].z = (jboolean)(SvIV(sv) != 0); break; case 'B': jv[ix++].b = (jbyte)SvIV(sv); break; case 'C': jv[ix++].c = (jchar)SvIV(sv); break; case 'S': jv[ix++].s = (jshort)SvIV(sv); break; case 'I': jv[ix++].i = (jint)SvIV(sv); break; case 'J': jv[ix++].j = (jlong)SvNV(sv); break; case 'F': jv[ix++].f = (jfloat)SvNV(sv); break; case 'D': jv[ix++].d = (jdouble)SvNV(sv); break; case '[': switch (*s++) { case 'Z': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jboolean* buf = (jboolean*)malloc(len * sizeof(jboolean)); int i; SV** esv; jbooleanArray ja = (*env)->NewBooleanArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jboolean)SvIV(*esv); (*env)->SetBooleanArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jboolean); jbooleanArray ja = (*env)->NewBooleanArray(env, len); (*env)->SetBooleanArrayRegion(env, ja, 0, len, (jboolean*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'B': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jbyte* buf = (jbyte*)malloc(len * sizeof(jbyte)); int i; SV** esv; jbyteArray ja = (*env)->NewByteArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jbyte)SvIV(*esv); (*env)->SetByteArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jbyte); jbyteArray ja = (*env)->NewByteArray(env, len); (*env)->SetByteArrayRegion(env, ja, 0, len, (jbyte*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'C': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jchar* buf = (jchar*)malloc(len * sizeof(jchar)); int i; SV** esv; jcharArray ja = (*env)->NewCharArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jchar)SvIV(*esv); (*env)->SetCharArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jchar); jcharArray ja = (*env)->NewCharArray(env, len); (*env)->SetCharArrayRegion(env, ja, 0, len, (jchar*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'S': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jshort* buf = (jshort*)malloc(len * sizeof(jshort)); int i; SV** esv; jshortArray ja = (*env)->NewShortArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jshort)SvIV(*esv); (*env)->SetShortArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jshort); jshortArray ja = (*env)->NewShortArray(env, len); (*env)->SetShortArrayRegion(env, ja, 0, len, (jshort*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'I': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jint* buf = (jint*)malloc(len * sizeof(jint)); int i; SV** esv; jintArray ja = (*env)->NewIntArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jint)SvIV(*esv); (*env)->SetIntArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jint); jintArray ja = (*env)->NewIntArray(env, len); (*env)->SetIntArrayRegion(env, ja, 0, len, (jint*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'J': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jlong* buf = (jlong*)malloc(len * sizeof(jlong)); int i; SV** esv; jlongArray ja = (*env)->NewLongArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jlong)SvNV(*esv); (*env)->SetLongArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jlong); jlongArray ja = (*env)->NewLongArray(env, len); (*env)->SetLongArrayRegion(env, ja, 0, len, (jlong*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'F': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jfloat* buf = (jfloat*)malloc(len * sizeof(jfloat)); int i; SV** esv; jfloatArray ja = (*env)->NewFloatArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jfloat)SvNV(*esv); (*env)->SetFloatArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jfloat); jfloatArray ja = (*env)->NewFloatArray(env, len); (*env)->SetFloatArrayRegion(env, ja, 0, len, (jfloat*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'D': if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; jdouble* buf = (jdouble*)malloc(len * sizeof(jdouble)); int i; SV** esv; jdoubleArray ja = (*env)->NewDoubleArray(env, len); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) buf[i] = (jdouble)SvNV(*esv); (*env)->SetDoubleArrayRegion(env, ja, 0, len, buf); free((void*)buf); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else if (SvPOK(sv)) { jsize len = sv_len(sv) / sizeof(jdouble); jdoubleArray ja = (*env)->NewDoubleArray(env, len); (*env)->SetDoubleArrayRegion(env, ja, 0, len, (jdouble*)SvPV(sv,n_a)); jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; break; case 'L': while (*s != ';') s++; s++; if (strnEQ(start, "[Ljava/lang/String;", 19)) { if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; int i; SV** esv; static jclass jcl = 0; jobjectArray ja; if (!jcl) jcl = (*env)->FindClass(env, "java/lang/String"); ja = (*env)->NewObjectArray(env, len, jcl, 0); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) { jobject str = (jobject)(*env)->NewStringUTF(env, SvPV(*esv,n_a)); (*env)->SetObjectArrayElement(env, ja, i, str); } jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else jv[ix++].l = (jobject)(void*)0; break; } /* FALL THROUGH */ default: if (SvROK(sv)) { SV* rv = (SV*)SvRV(sv); if (SvOBJECT(rv)) jv[ix++].l = (jobject)(void*)SvIV(rv); else if (SvTYPE(rv) == SVt_PVAV) { jsize len = av_len((AV*)rv) + 1; int i; SV** esv; static jclass jcl = 0; jobjectArray ja; if (!jcl) jcl = (*env)->FindClass(env, "java/lang/Object"); ja = (*env)->NewObjectArray(env, len, jcl, 0); for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) { if (SvROK(*esv) && (rv = SvRV(*esv)) && SvOBJECT(rv)) { (*env)->SetObjectArrayElement(env, ja, i, (jobject)(void*)SvIV(rv)); } else { jobject str = (jobject)(*env)->NewStringUTF(env, SvPV(*esv,n_a)); (*env)->SetObjectArrayElement(env, ja, i, str); } } jv[ix++].l = (jobject)ja; } else jv[ix++].l = (jobject)(void*)0; } else jv[ix++].l = (jobject)(void*)0; break; } break; case 'L': if (!SvROK(sv) || strnEQ(s, "java/lang/String;", 17)) { s += 17; jv[ix++].l = (jobject)(*env)->NewStringUTF(env, (char*) SvPV(sv,n_a)); break; } while (*s != ';') s++; s++; if (SvROK(sv)) { SV* rv = SvRV(sv); jv[ix++].l = (jobject)(void*)SvIV(rv); } break; case ')': croak("too many arguments, signature: %s", sig); goto cleanup; default: croak("panic: malformed signature: %s", s-1); goto cleanup; } } if (*s != ')') { croak("not enough arguments, signature: %s", sig); goto cleanup; } return jv;cleanup: safefree((char*)jv); return 0;}static intnot_here(char *s){ croak("%s not implemented on this architecture", s); return -1;}static doubleconstant(char *name, int arg){ errno = 0; switch (*name) { case 'A': break; case 'B': break; case 'C': break; case 'D': break; case 'E': break; case 'F': break; case 'G': break; case 'H': break; case 'I': break; case 'J': if (strEQ(name, "JNI_ABORT"))#ifdef JNI_ABORT return JNI_ABORT;#else goto not_there;#endif if (strEQ(name, "JNI_COMMIT"))#ifdef JNI_COMMIT return JNI_COMMIT;#else goto not_there;#endif if (strEQ(name, "JNI_ERR"))#ifdef JNI_ERR return JNI_ERR;#else goto not_there;#endif if (strEQ(name, "JNI_FALSE"))#ifdef JNI_FALSE return JNI_FALSE;#else goto not_there;#endif if (strEQ(name, "JNI_H"))#ifdef JNI_H#ifdef WIN32 return 1;#else return JNI_H;#endif#else goto not_there;#endif if (strEQ(name, "JNI_OK"))#ifdef JNI_OK return JNI_OK;#else goto not_there;#endif if (strEQ(name, "JNI_TRUE"))#ifdef JNI_TRUE return JNI_TRUE;#else goto not_there;#endif break; case 'K': break; case 'L': break; case 'M': break; case 'N': break; case 'O': break; case 'P': break; case 'Q': break; case 'R': break; case 'S': break; case 'T': break; case 'U': break; case 'V': break; case 'W': break; case 'X': break; case 'Y': break; case 'Z': break; } errno = EINVAL; return 0;not_there: errno = ENOENT; return 0;}#define FETCHENV jplcurenv#define RESTOREENV jplcurenv = envMODULE = JNI PACKAGE = JNI PROTOTYPES: ENABLEdoubleconstant(name,arg) char * name int argjintGetVersion() JNIEnv * env = FETCHENV; CODE: { RETVAL = (*env)->GetVersion(env); RESTOREENV; } OUTPUT: RETVALjclassDefineClass(name, loader, buf) JNIEnv * env = FETCHENV; STRLEN tmplen = NO_INIT; jsize buf_len_ = NO_INIT; const char * name jobject loader const jbyte * buf CODE: {#ifdef KAFFE RETVAL = (*env)->DefineClass(env, loader, buf, (jsize)buf_len_);#else RETVAL = (*env)->DefineClass(env, name, loader, buf, (jsize)buf_len_); #endif RESTOREENV; } OUTPUT: RETVALjclassFindClass(name) JNIEnv * env = FETCHENV; const char * name CODE: { RETVAL = (*env)->FindClass(env, name); RESTOREENV; } OUTPUT: RETVALjclassGetSuperclass(sub) JNIEnv * env = FETCHENV; jclass sub CODE: { RETVAL = (*env)->GetSuperclass(env, sub); RESTOREENV; } OUTPUT: RETVALjbooleanIsAssignableFrom(sub, sup) JNIEnv * env = FETCHENV; jclass sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -