Como acessar o método Java em um aplicativo C ++

Apenas uma pergunta simples: é possível chamar uma function java do c / c ++?

Sim, você pode, mas é um pouco complicado, e funciona de uma maneira refletiva / não segura (exemplo usa a API C ++ que é um pouco mais limpa que a versão C). Neste caso, cria uma instância da VM Java a partir do código C. Se seu nativo chamado for chamado pela primeira vez de Java, não será necessário construir uma instância de VM

#include #include 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(); } 

Para compilar (no 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 

Nota: o código de retorno de cada um desses methods deve ser verificado para implementar o tratamento correto do erro (ignorei isso por conveniência). Por exemplo

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

Sim, é, mas você tem que fazer isso via JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html

Existem muitos caminhos. Aqui estão algumas idéias. Além disso, as pontes comerciais Java-COM permitem a comunicação COM de c ++ para java (se você estiver usando o Windows). Você também deve olhar para a CNI .

Dê uma olhada na API de invocação . Isso permite que você carregue e inicie uma JVM a partir de seu aplicativo nativo e invoque methods a partir do aplicativo.

Resumidamente (do documento vinculado)

 /* 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); 

Sim, você pode chamar uma function Java de C ++ ou C, mas a menos que você esteja usando algo como COM ou CORBA (ou outra ferramenta de terceiros que eu provavelmente não conheço), você terá que fazer isso no contexto de JNI.

Todo o procedimento para chamar um método Java a partir do código nativo é descrito no Capítulo 4 na seção 4.2 chamado “Métodos de Chamada” no guia JNI pdf da Sun, que você pode encontrar aqui .

A function a seguir permite criar a 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; } 

Compile o famoso programa Hello World . A function a seguir tenta chamar o método principal do programa 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; } 

Agora coloque a function create_vm e a function principal em um único arquivo cpp, inclua jni.h e compile-o. Eu usei MinGW no windows.

 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 

Exection Agora, se você executar o exe criado, você receberá um erro. jvm.dll não encontrado . Coloque C:\Program Files\Java\jre6\bin\client em sua variável de ambiente PATH. Agora você pode executar o arquivo exe.

Nota: Não desloque o arquivo jvm.dll.

Após codificar os exemplos acima, você precisa fazer alguma configuração no seu projeto.

Etapas para vincular o jvm.lib ao seu projeto no Visual Studio:

  • Clique com o botão direito no projeto -> propriedades.
  • Na checkbox de diálogo Properties, adicione jvm.lib na área Linker-> Input-> AdditionalDependencies.
  • Por último, escreva o caminho jvm.lib (como “C: \ Programas \ Java \ jdk1.7.0_60 \ lib”) em Linker-> General-> AdditionalLibraryDirectories

Após essas etapas, seu projeto pode se conectar ao jvm e funcionar bem.