📄 java.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Sam Ruby (rubys@us.ibm.com) | +----------------------------------------------------------------------+*//* $Id: java.c,v 1.69.4.2.8.2 2007/01/01 09:46:44 sebastian Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif/* * This module implements Zend OO syntax overloading support for Java * components using JNI and reflection. */#include "php.h"#include "zend_compile.h"#include "php_ini.h"#include "php_globals.h"#if HAVE_JAVAVM_JAVAVM_H#include <JavaVM/JavaVM.h>#include <JavaVM/jni.h>#define JNI_12#else#include <jni.h>#endif#ifdef PHP_WIN32#include "win32/winutil.h"#define DL_ERROR php_win_err#endif#include <stdio.h>#define IS_EXCEPTION 86/***************************************************************************/#ifndef KAFFE#ifndef JNI_11#ifndef JNI_12#ifdef JNI_VERSION_1_2#define JNI_12#else#define JNI_11#endif#endif#endif#endif#ifdef PHP_WIN32#ifdef JNI_12#define JAVALIB "jvm.dll"#else#define JAVALIB "javai.dll"#endif#else#endif/***************************************************************************/static int le_jobject = 0;static char *classpath = 0;static char *libpath = 0;static char *javahome = 0;static char *javalib = 0;static void *dl_handle = 0;/* {{{ ZEND_BEGIN_MODULE_GLOBALS */ZEND_BEGIN_MODULE_GLOBALS(java) JavaVM *jvm; JNIEnv *jenv; jobject php_reflect; jclass reflect_class;ZEND_END_MODULE_GLOBALS(java)/* }}} */#ifdef ZTS# define JG(v) TSRMG(java_globals_id, zend_java_globals *, v)#else# define JG(v) (java_globals.v)#endifZEND_DECLARE_MODULE_GLOBALS(java)static zend_class_entry java_class_entry;static PHP_INI_MH(OnIniUpdate){ if (new_value) *(char**)mh_arg1 = new_value; return SUCCESS;}/* {{{ PHP_INI_BEGIN */PHP_INI_BEGIN() PHP_INI_ENTRY1("java.class.path", NULL, PHP_INI_SYSTEM, OnIniUpdate, &classpath)#ifndef JNI_11 PHP_INI_ENTRY1("java.home", NULL, PHP_INI_SYSTEM, OnIniUpdate, &javahome) PHP_INI_ENTRY1("java.library.path", NULL, PHP_INI_SYSTEM,OnIniUpdate, &libpath)#endif#ifdef JAVALIB PHP_INI_ENTRY1("java.library", JAVALIB, PHP_INI_SYSTEM, OnIniUpdate, &javalib)#else PHP_INI_ENTRY1("java.library", NULL, PHP_INI_SYSTEM, OnIniUpdate, &javalib)#endifPHP_INI_END()/* }}} *//***************************************************************************//* {{{ jvm_destroy *//* * Destroy a Java Virtual Machine. */void jvm_destroy(TSRMLS_D) { if (JG(php_reflect)) (*JG(jenv))->DeleteGlobalRef(JG(jenv), JG(php_reflect)); JG(php_reflect) = 0;}/* }}} *//* {{{ addJVMOption *//* * Create a Java Virtual Machine. * - class.path, home, and library.path are read out of the INI file * - appropriate (pre 1.1, JDK 1.1, and JDK 1.2) initialization is performed * - net.php.reflect class file is located */#ifdef JNI_12static void addJVMOption(JavaVMInitArgs *vm_args, char *name, char *value) { char *option = (char*) malloc(strlen(name) + strlen(value) + 1); strcpy(option, name); strcat(option, value); vm_args->options[vm_args->nOptions++].optionString = option;}#endif/* }}} *//* {{{ jvm_create */static int jvm_create(TSRMLS_D) { int rc; jobject local_php_reflect; jthrowable error; jint (JNICALL *JNI_CreateVM)(const void*, const void*, void*);#ifndef JNI_12 jint (JNICALL *JNI_DefaultArgs)(void*);#endif#ifdef JNI_11 JDK1_1InitArgs vm_args;#else JavaVMInitArgs vm_args;#ifdef JNI_12 JavaVMOption options[3];#endif#endif if (javalib) { dl_handle = DL_LOAD(javalib); if (!dl_handle) { php_error(E_ERROR, "Unable to load Java Library %s, error: %s", javalib, DL_ERROR()); return -1; } }#ifndef JAVALIB if (!dl_handle) JNI_CreateVM = &JNI_CreateJavaVM; else#endif JNI_CreateVM = (jint (JNICALL *)(const void*, const void*, void*)) DL_FETCH_SYMBOL(dl_handle, "JNI_CreateJavaVM"); if (!JNI_CreateVM) { php_error(E_ERROR, "Unable to locate CreateJavaVM function"); return -1; }#ifdef JNI_12 vm_args.version = JNI_VERSION_1_2; vm_args.ignoreUnrecognized = JNI_FALSE; vm_args.options = options; vm_args.nOptions = 0; if (classpath) addJVMOption(&vm_args, "-Djava.class.path=", classpath); if (javahome) addJVMOption(&vm_args, "-Djava.home=", javahome); if (libpath) addJVMOption(&vm_args, "-Djava.library.path=", libpath);#else#ifndef JAVALIB if (!dl_handle) JNI_DefaultArgs = &JNI_GetDefaultJavaVMInitArgs; else#endif JNI_DefaultArgs = (jint (JNICALL *)(void*)) DL_FETCH_SYMBOL(dl_handle, "JNI_GetDefaultJavaVMInitArgs"); if (!JNI_DefaultArgs) { php_error(E_ERROR, "Unable to locate GetDefaultJavaVMInitArgs function"); return -1; } vm_args.version=0x00010001; (*JNI_DefaultArgs)(&vm_args); if (!classpath) classpath = ""; vm_args.classpath = classpath;#ifdef KAFFE vm_args.classhome = javahome; vm_args.libraryhome = libpath;#endif#endif rc = (*JNI_CreateVM)(&JG(jvm), &JG(jenv), &vm_args); if (rc) { php_error(E_ERROR, "Unable to create Java Virtual Machine"); return rc; } JG(reflect_class) = (*JG(jenv))->FindClass(JG(jenv), "net/php/reflect"); error = (*JG(jenv))->ExceptionOccurred(JG(jenv)); if (error) { jclass errClass; jmethodID toString; jobject errString; const char *errAsUTF; jboolean isCopy; JNIEnv *jenv = JG(jenv); (*jenv)->ExceptionClear(jenv); errClass = (*jenv)->GetObjectClass(jenv, error); toString = (*jenv)->GetMethodID(jenv, errClass, "toString", "()Ljava/lang/String;"); errString = (*jenv)->CallObjectMethod(jenv, error, toString); errAsUTF = (*jenv)->GetStringUTFChars(jenv, errString, &isCopy); php_error(E_ERROR, "%s", errAsUTF); if (isCopy) (*jenv)->ReleaseStringUTFChars(jenv, error, errAsUTF); jvm_destroy(TSRMLS_C); return -1; } local_php_reflect = (*JG(jenv))->AllocObject(JG(jenv), JG(reflect_class)); JG(php_reflect) = (*JG(jenv))->NewGlobalRef(JG(jenv), local_php_reflect); return rc;}/* }}} *//***************************************************************************//* {{{ _java_makeObject */static jobject _java_makeObject(pval* arg TSRMLS_DC){ JNIEnv *jenv = JG(jenv); jobject result; pval **handle; int type; jmethodID makeArg; jclass hashClass; switch (Z_TYPE_P(arg)) { case IS_STRING: result=(*jenv)->NewByteArray(jenv, Z_STRLEN_P(arg)); (*jenv)->SetByteArrayRegion(jenv, (jbyteArray)result, 0, Z_STRLEN_P(arg), Z_STRVAL_P(arg)); break; case IS_OBJECT: zend_hash_index_find(Z_OBJPROP_P(arg), 0, (void*)&handle); result = zend_list_find(Z_LVAL_PP(handle), &type); break; case IS_BOOL: makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg", "(Z)Ljava/lang/Object;"); result = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg, (jboolean)(Z_LVAL_P(arg))); break; case IS_LONG: makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg", "(J)Ljava/lang/Object;"); result = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg, (jlong)(Z_LVAL_P(arg))); break; case IS_DOUBLE: makeArg = (*jenv)->GetMethodID(jenv, JG(reflect_class), "MakeArg", "(D)Ljava/lang/Object;"); result = (*jenv)->CallObjectMethod(jenv, JG(php_reflect), makeArg, (jdouble)(Z_DVAL_P(arg))); break; case IS_ARRAY: { jobject jkey, jval; zval **value; zval key; char *string_key; ulong num_key; jobject jold; jmethodID put, init; hashClass = (*jenv)->FindClass(jenv, "java/util/Hashtable"); init = (*jenv)->GetMethodID(jenv, hashClass, "<init>", "()V"); result = (*jenv)->NewObject(jenv, hashClass, init); put = (*jenv)->GetMethodID(jenv, hashClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); /* Iterate through hash */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(arg)); while(zend_hash_get_current_data(Z_ARRVAL_P(arg), (void**)&value) == SUCCESS) { jval = _java_makeObject(*value TSRMLS_CC); switch (zend_hash_get_current_key(Z_ARRVAL_P(arg), &string_key, &num_key, 0)) { case HASH_KEY_IS_STRING: Z_TYPE(key) = IS_STRING; Z_STRVAL(key) = string_key; Z_STRLEN(key) = strlen(string_key); jkey = _java_makeObject(&key TSRMLS_CC); break; case HASH_KEY_IS_LONG: Z_TYPE(key) = IS_LONG; Z_LVAL(key) = num_key; jkey = _java_makeObject(&key TSRMLS_CC); break; default: /* HASH_KEY_NON_EXISTANT */ jkey = 0; } jold = (*jenv)->CallObjectMethod(jenv, result, put, jkey, jval); if (Z_TYPE_PP(value) != IS_OBJECT) (*jenv)->DeleteLocalRef(jenv, jval); zend_hash_move_forward(Z_ARRVAL_P(arg)); } break; } default: result=0; } return result;}/* }}} *//***************************************************************************//* {{{ _java_makeArray */static jobjectArray _java_makeArray(int argc, pval** argv TSRMLS_DC){ JNIEnv *jenv = JG(jenv); jclass objectClass = (*jenv)->FindClass(jenv, "java/lang/Object"); jobjectArray result = (*jenv)->NewObjectArray(jenv, argc, objectClass, 0); jobject arg; int i; for (i=0; i<argc; i++) { arg = _java_makeObject(argv[i] TSRMLS_CC); (*jenv)->SetObjectArrayElement(jenv, result, i, arg); if (Z_TYPE_P(argv[i]) != IS_OBJECT) (*jenv)->DeleteLocalRef(jenv, arg); } return result;}/* }}} *//* {{{ checkError */static int checkError(pval *value){ if (Z_TYPE_P(value) == IS_EXCEPTION) { php_error(E_WARNING, "%s", Z_STRVAL_P(value)); efree(Z_STRVAL_P(value)); ZVAL_FALSE(value); return 1; }; return 0;}/* }}} *//***************************************************************************//* {{{ java_call_function_handler *//* * Invoke a method on an object. If method name is "java", create a new * object instead. */void java_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference){ JNIEnv *jenv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -