阅读背景:

JNI_CreateJavaVM函数分析_idongzi的博客

来源:互联网 

22222

jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args)
{
    const JavaVMInitArgs* args = (JavaVMInitArgs*) vm_args;
    JNIEnvExt* pEnv = NULL;
    JavaVMExt* pVM = NULL;
    const char** argv;
    int argc = 0;
    int i, curOpt;
    int result = JNI_ERR;
    bool checkJni = false;
    bool warnError = true;
    bool forceDataCopy = false;

    if (args->version < JNI_VERSION_1_2)
        return JNI_EVERSION;

    // TODO: don't allow creation of multiple VMs -- one per customer for now

    /* zero globals; not strictly necessary the first time a VM is started */
    memset(&gDvm, 0, sizeof(gDvm));//gDvm全局变量

    /*
     * Set up structures for JNIEnv and VM.
     */
    //pEnv = (JNIEnvExt*) malloc(sizeof(JNIEnvExt));
    pVM = (JavaVMExt*) malloc(sizeof(JavaVMExt));

    //memset(pEnv, 0, sizeof(JNIEnvExt));
    //pEnv->funcTable = &gNativeInterface;
    //pEnv->vm = pVM;
    memset(pVM, 0, sizeof(JavaVMExt));
    pVM->funcTable = &gInvokeInterface;
    pVM->envList = pEnv;
    dvmInitMutex(&pVM->envListLock);

    argv = (const char**) malloc(sizeof(char*) * (args->nOptions));
    memset(argv, 0, sizeof(char*) * (args->nOptions));

    curOpt = 0;

    /*
     * Convert JNI args to argv.
     *
     * We have to pull out vfprintf/exit/abort, because they use the
     * "extraInfo" field to pass function pointer "hooks" in.  We also
     * look for the -Xcheck:jni stuff here.
     */
    for (i = 0; i < args->nOptions; i++) {
        const char* optStr = args->options[i].optionString;

        if (optStr == NULL) {
            fprintf(stderr, "ERROR: arg %d string was null\n", i);
            goto bail;
        } else if (strcmp(optStr, "vfprintf") == 0) {
            gDvm.vfprintfHook = args->options[i].extraInfo;
        } else if (strcmp(optStr, "exit") == 0) {
            gDvm.exitHook = args->options[i].extraInfo;
        } else if (strcmp(optStr, "abort") == 0) {
            gDvm.abortHook = args->options[i].extraInfo;
        } else if (strcmp(optStr, "-Xcheck:jni") == 0) {
            checkJni = true;
        } else if (strncmp(optStr, "-Xjniopts:", 10) == 0) {
            const char* jniOpts = optStr + 9;
            while (jniOpts != NULL) {
                jniOpts++;      /* skip past ':' or ',' */
                if (strncmp(jniOpts, "warnonly", 8) == 0) {
                    warnError = false;
                } else if (strncmp(jniOpts, "forcecopy", 9) == 0) {
                    forceDataCopy = true;
                } else {
                    LOGW("unknown jni opt starting at '%s'\n", jniOpts);
                }
                jniOpts = strchr(jniOpts, ',');
            }
        } else {
            /* regular option */
            argv[curOpt++] = optStr;
        }
    }
    argc = curOpt;

    if (checkJni) {
        dvmUseCheckedJniVm(pVM);
        pVM->useChecked = true;
    }
    pVM->warnError = warnError;
    pVM->forceDataCopy = forceDataCopy;

    /* set this up before initializing VM, so it can create some JNIEnvs */
    gDvm.vmList = (JavaVM*) pVM;

    /*
     * Create an env for main thread.  We need to have something set up
     * here because some of the class initialization we do when starting
     * up the VM will call into native code.
     */
    pEnv = (JNIEnvExt*) dvmCreateJNIEnv(NULL);

    /* initialize VM */
    gDvm.initializing = true;
    if (dvmStartup(argc, argv, args->ignoreUnrecognized, (JNIEnv*)pEnv) != 0) {
        free(pEnv);
        free(pVM);
        goto bail;
    }

    /*
     * Success!  Return stuff to caller.
     */
    dvmChangeStatus(NULL, THREAD_NATIVE);
    *p_env = (JNIEnv*) pEnv;
    *p_vm = (JavaVM*) pVM;
    result = JNI_OK;

bail:
    gDvm.initializing = false;
    if (result == JNI_OK)
        LOGV("JNI_CreateJavaVM succeeded\n");
    else
        LOGW("JNI_CreateJavaVM failed\n");
    free(argv);
    return result;
}
jint JNI_CreateJavaVM(JavaVM** p_vm,



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: