Una simple pregunta: ¿Es posible llamar a una función java desde c/C++?Cómo acceder al método Java en una aplicación C++
Respuesta
Sí, puede, pero es un poco intrincado, y funciona de manera reflexiva/no segura (por ejemplo, utiliza la API api que es un poco más limpia que la versión C). En este caso, crea una instancia de Java VM desde dentro del código C. Si su nativa llamada es primero ser llamado desde Java, entonces no hay necesidad de construir una instancia de 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();
}
Para compilar (en 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: que el código de retorno de cada uno de estos métodos deben verificarse para implementar el manejo correcto de errores (he ignorado esto por conveniencia). P.ej.
str = env->GetStringUTFChars(jstr, NULL);
if (str == NULL) {
return; /* out of memory */
}
Sí lo es, pero hay que hacerlo a través de JNI: http://java.sun.com/javase/6/docs/technotes/guides/jni/index.html
He visto que JNI solía llamar a C++ desde Java. No sabía que funcionó a la inversa también. – Kieveli
Extraño, siempre he visto que se usa más comúnmente para proporcionar acceso a bibliotecas C++ desde Java, pero funciona en ambos sentidos. –
Sí, se puede llamar a una función Java desde C++ o C, pero a menos que estés usando algo como COM o CORBA (u otra herramienta de tercera partes que probablemente no soy consciente de) podrás tiene que hacer esto en el contexto de JNI.
Todo el procedimiento para llamar a un método Java de código nativo se describe en el capítulo 4 en el apartado 4.2 denominado "Llamar a Métodos" en la guía de JNI pdf de Sun, que se puede encontrar here.
Eche un vistazo a invocation API. Esto le permite cargar e iniciar una JVM desde dentro de su aplicación nativa, y luego invocar métodos desde la aplicación.
En pocas palabras (del documento relacionado)
/* 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);
La siguiente función le permite crear la máquina virtual.
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;
}
Compilar el famoso programa Hello World. La siguiente función intenta llamar al método principal del 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;
}
función create_vm Ahora ponga y función principal en un solo archivo CPP, incluyen jni.h y compilarlo. Usé MinGW en 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 Ahora bien, si se ejecuta el exe creado, recibirá un error. jvm.dll not found. Ponga C:\Program Files\Java\jre6\bin\client
en su variable de entorno PATH. Ahora puede ejecutar el archivo exe.
Nota: No desplace el archivo jvm.dll.
Después de codificar los ejemplos anteriores, debe realizar alguna configuración en su proyecto.
Pasos para enlazar la jvm.lib a su proyecto en Visual Studio:
- Haga clic derecho sobre el proyecto -> propiedades.
- En el cuadro de diálogo Propiedades, agregue jvm.lib en el área Enlazador-> Entrada-> Otras dependencias.
- Por último escribir camino jvm.lib (como "C: \ Archivos de programa \ Java \ jdk1.7.0_60 \ lib") bajo Linker-> General-> AdditionalLibraryDirectories
Después de esos pasos, su proyecto puede enlace a jvm y funciona bien.
- 1. java.lang.IllegalAccessError: intentado acceder al método
- 2. Cómo acceder a un recurso binario en una aplicación C#
- 3. WPF: cómo acceder al método declarado en App.xaml.cs?
- 4. ¿Cómo acceder al método HttpServerUtility.MapPath en un subproceso o temporizador?
- 5. método indefinido `default_scoped? ' al acceder al osciloscopio
- 6. ¿Cómo acceder a un método estático en C#?
- 7. ¿Cómo puedo acceder al método de clase y al método de instancia en ruby?
- 8. Problema al acceder al método expuesto ExternalInterface en Google Chrome
- 9. Cómo llamar al método vararg Java desde C con valist
- 10. C# Cómo acceder al campo estático de una estructura pública
- 11. ¿Cómo acceder al control C# WPF de manera segura?
- 12. Cómo llamar al método de clase abstracta en java
- 13. Escribiendo al registro en una aplicación C#
- 14. ¿Incrustar Java en una aplicación C++?
- 15. Cómo acceder al miembro protegido
- 16. ¿Cómo acceder al índice en el objeto IEnumerable en C#?
- 17. Método de llamada en undeploy desde una aplicación web Java
- 18. ¿Es posible llamar al método dentro de una aplicación Java desde una JVM diferente?
- 19. Error al acceder al shell sqlite3 desde la aplicación django
- 20. Zeromq: Cómo acceder al mensaje tcp en C++
- 21. ¿Cómo acceder a Java Enum en ColdFusion?
- 22. Java: ¿Cómo puedo acceder al campo de una clase con un nombre almacenado en una variable?
- 23. Usando call_user_function para acceder al método padre en PHP
- 24. Se puede acceder al método estático en Java utilizando la instancia de objeto
- 25. ¿Cómo acceder al archivo de recursos en C#?
- 26. ¿Cómo acceder al archivo de propiedades desde la aplicación web Java EE?
- 27. Llamadas al método de captura en Java
- 28. Ver anotaciones Java en una llamada al método
- 29. ¿Cómo escribir un cliente Java para acceder al archivo WSDL?
- 30. Llamando al método C# dentro de un programa Java
+1 por ejemplo. ¿Podría también querer incluir enlaces/ejemplos de configurar los encabezados, firmas de funciones, etc.? – poundifdef
su solución es genial, pero ¿cómo cargar o establecer classpath que hemos creado? Por ejemplo HelloWorld.java es decir env_> FindClass ("HelloWorld"); ' –