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));
/*
* 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;
}
JNI_CreateJavaVM函数
最新推荐文章于 2023-06-21 10:09:30 发布