如何在 C 应用程序中访问 Java 方法

新手上路,请多包涵

只是一个简单的问题:是否可以从 c/c++ 调用 java 函数?

原文由 Hemant 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 623
2 个回答

是的,你可以,但它有点复杂,并且以反射/非类型安全的方式工作(示例使用比 C 版本更干净的 C++ api)。在这种情况下,它从 C 代码中创建 Java VM 的实例。如果您的本机代码首先从 Java 调用,则无需构造 VM 实例

#include<jni.h>
#include<stdio.h>

int main(int argc, char** argv) {

    JavaVM *vm;
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    vm_args.version = JNI_VERSION_1_2;
    vm_args.nOptions = 0;
    vm_args.ignoreUnrecognized = 1;

    // Construct a VM
    jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);

    // Construct a String
    jstring jstr = env->NewStringUTF("Hello World");

    // First get the class that contains the method you need to call
    jclass clazz = env->FindClass("java/lang/String");

    // Get the method that you want to call
    jmethodID to_lower = env->GetMethodID(clazz, "toLowerCase",
                                      "()Ljava/lang/String;");
    // Call the method on the object
    jobject result = env->CallObjectMethod(jstr, to_lower);

    // Get a C-style string
    const char* str = env->GetStringUTFChars((jstring) result, NULL);

    printf("%s\n", str);

    // Clean up
    env->ReleaseStringUTFChars(jstr, str);

    // Shutdown the VM.
    vm->DestroyJavaVM();
}

编译(在 Ubuntu 上):

 g++ -I/usr/lib/jvm/java-6-sun/include \
    -I/usr/lib/jvm/java-6-sun/include/linux \
    -L/usr/lib/jvm/java-6-sun/jre/lib/i386/server/ -ljvm jnitest.cc

注意:为了实现正确的错误处理,应该检查每个方法的返回码(为方便起见,我忽略了这一点)。例如

str = env->GetStringUTFChars(jstr, NULL);
if (str == NULL) {
    return; /* out of memory */
}

原文由 Michael Barker 发布,翻译遵循 CC BY-SA 4.0 许可协议

以下函数允许您创建 VM。

 JNIEnv* create_vm(JavaVM ** jvm)
{
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options[2];

    options[0].optionString = "-Djava.class.path=.";
    options[1].optionString = "-DXcheck:jni:pedantic";

    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 2;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_TRUE; // remove unrecognized options

    int ret = JNI_CreateJavaVM(jvm, (void**) &env, &vm_args);
    if (ret < 0) printf("\n<<<<< Unable to Launch JVM >>>>>\n");
    return env;
}

编译著名的 Hello World 程序。以下函数尝试调用 HelloWorld 程序的 main 方法。

 int main(int argc, char* argv[])
{
    JNIEnv* env;
    JavaVM* jvm;

    env = create_vm(&jvm);

    if (env == NULL) return 1;

    jclass myClass = NULL;
    jmethodID main = NULL;

    myClass = env->FindClass("HelloWorld");

    if (myClass != NULL)
        main = env->GetStaticMethodID(myClass, "main", "([Ljava/lang/String;)V");
    else
        printf("Unable to find the requested class\n");

    if (main != NULL)
    {
       env->CallStaticVoidMethod( myClass, main, " ");

    }else printf("main method not found") ;

    jvm->DestroyJavaVM();
    return 0;
}

现在将 create_vm 函数和 main 函数放在一个 cpp 文件中,包含 jni.h 并编译它。我在 Windows 上使用了 MinGW。

 g++ -D_JNI_IMPLEMENTATION_ -I"C:\Program Files\Java\jdk1.6.0_32\include" -I"C:\Program Files\Java\jdk1.6.0_32\include\win32" hello.cpp -L"C:\Program Files\Java\jre6\bin\client" -ljvm -o hello.exe

执行 现在如果你运行创建的exe,你会得到一个错误。 找不到 jvm.dll 。将 C:\Program Files\Java\jre6\bin\client 放入 PATH 环境变量中。现在你可以运行exe文件了。

注意:不要替换 jvm.dll 文件。

原文由 Sorter 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题