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

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

是的你可以,但它有点复杂,并且以reflection/非types安全的方式工作(例如使用比C版本更清洁的C ++ api)。 在这种情况下,它将在C代码中创build一个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 

注意:为了实现正确的error handling,我们应该检查每个方法的返回代码(为了方便,我忽略了这个)。 例如

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

是的,但你必须通过JNI: http : //java.sun.com/javase/6/docs/technotes/guides/jni/index.html

有很多方法。 这里有一些想法。 另外,商业Java-COM桥允许从c ++到java的通信(如果你使用的是Windows)。 你也应该看看CNI 。

是的,你可以从C ++或C调用Java函数,但是除非你使用COM或者CORBA(或者我可能不知道的另一个第三方工具),否则你必须在上下文中的JNI。

从本地代码中调用Java方法的整个过程在Sun的JNI指南pdf中的第4章4.2节中称为“调用方法”中介绍,您可以在这里find它。

看看调用API 。 这使您可以从本机应用程序中加载和启动JVM,然后从应用程序调用JVM。

简而言之(从链接的文档)

 /* load and initialize a Java VM, return a JNI interface * pointer in env */ JNI_CreateJavaVM(&jvm, &env, &vm_args); /* invoke the Main.test method using the JNI */ jclass cls = env->FindClass("Main"); jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V"); env->CallStaticVoidMethod(cls, mid, 100); 

以下function允许您创buildVM。

 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程序的主要方法。

 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并编译。 我在窗户上使用了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 

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

注意:不要取代jvm.dll文件。

在编码上面的例子之后,你需要在你的项目上做一些configuration。

在Visual Studio中将jvm.lib链接到您的项目的步骤:

  • 右键点击项目 – >属性。
  • 在属性对话框中,在链接器 – >input – >附加依赖关系区域添加jvm.lib。
  • 最后在Linker-> General-> AdditionalLibraryDirectories下写jvm.lib的path(如“C:\ Program Files \ Java \ jdk1.7.0_60 \ lib”)

完成这些步骤之后,您的项目可以链接到jvm并且运行良好。