首页 > 解决方案 > 在 OSX 中通过 JNI_CreateJavaVM 启动 JVM 仅限控制台

问题描述

我正在尝试从我的 C/ObjC 程序启动 JVM,但是在 Catalina 上显示可视元素(例如窗口)时遇到了一些问题。

使用非可视项目的程序部分,即控制台和System.out工作正常。但是没有出现任何应用程序窗口,尽管出现了一个正确的 Dock 图标,单击它时它什么也不做。

我编写了一个辅助函数来启动 JVM。作为论据它有

我看着我,我错过了一些东西,但我不知道是什么。有任何想法吗?

这是代码:

typedef jint (*JNI_CreateJavaVM_f)(JavaVM **, void **, void *);

int launchjvm(char *jvmlib, char **jvmopts, int c_jvmopts, char **args, int c_args, char *mainclass)
{
    JavaVM *vm;
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options[c_jvmopts];

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    memset(&vm_args, 0, sizeof(vm_args));
    vm_args.version = JNI_VERSION_1_8;
    vm_args.ignoreUnrecognized = JNI_TRUE;

    for (int i = 0; i < c_jvmopts; i++)
        options[i].optionString = jvmopts[i];
    vm_args.options = options;
    vm_args.nOptions = c_jvmopts;

    void *lib_handle = dlopen(jvmlib, RTLD_LOCAL | RTLD_LAZY);
    if (!lib_handle)
    {
        printf("[%s] Unable to load library: %s\n", __FILE__, dlerror());
        return 1;
    }
    JNI_CreateJavaVM_f JNI_CreateJavaVM = dlsym(lib_handle, "JNI_CreateJavaVM");
    if (!JNI_CreateJavaVM)
    {
        printf("[%s] Unable to get symbol: %s\n", __FILE__, dlerror());
        return 1;
    }

    jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
    if (res != JNI_OK)
    {
        printf("Failed to create Java VM\n");
        return res;
    }

    jclass cls = (*env)->FindClass(env, mainclass);
    if (cls == NULL)
    {
        printf("Failed to find %s class\n", mainclass);
        return 1;
    }

    jmethodID mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
    if (mid == NULL)
    {
        printf("Failed to find main function in class %s\n", mainclass);
        return 2;
    }

    jobjectArray main_args = (*env)->NewObjectArray(env, c_args, (*env)->FindClass(env, "java/lang/String"), NULL);
    for(int i = 0 ; i < c_args ; i++)
        (*env)->SetObjectArrayElement(env, main_args, i, (*env)->NewStringUTF(env, args[i]));

    int result = 0;
    (*env)->CallStaticVoidMethod(env, cls, mid, main_args);
    if ((*env)->ExceptionOccurred(env)) { // check if an exception occurred
        (*env)->ExceptionDescribe(env); // print the stack trace
        result = -1;
    }

    (*vm)->DestroyJavaVM(vm);
    [pool drain];
    return result;
}

标签: cocoajvmjava-native-interfacejvm-arguments

解决方案


推荐阅读