tutorial nazareno ejemplos descargar java c++ c jni

java - nazareno - Llamadas JNI diferentes en C vs C++?



jni nazareno (5)

Así que tengo el siguiente código en C que utiliza la interfaz nativa de Java, sin embargo, me gustaría convertir esto a C ++ pero no estoy seguro de cómo hacerlo.

#include <jni.h> #include <stdio.h> #include "InstanceMethodCall.h" JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj) { jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V"); if (mid == NULL) { return; /* method not found */ } printf("In C/n"); (*env)->CallVoidMethod(env, obj, mid); }

Programa Java:

class InstanceMethodCall { private native void nativeMethod(); private void callback() { System.out.println("In Java"); } public static void main(String args[]) { InstanceMethodCall c = new InstanceMethodCall(); c.nativeMethod(); } static { System.loadLibrary("InstanceMethodCall"); } }

¿Cuáles son las diferencias en las que JNI interactúa con C y C ++? Cualquier ayuda es muy apreciada.

Gracias pete


¿Has intentado envolver tu código C en una extern "C" Consulte C ++ Faq Lite para obtener más información y otros mecanismos posibles para permitirle usar su código C con C ++.


El primer código de un C ++ correcto, ¿no es así? Así que, ¡listo!

En serio, ¿qué quieres cambiar en ese código? ¿Por qué?


Ha pasado un tiempo desde que toqué el C ++ estándar, pero lo intentaré de todos modos.

" (*env)-> " me parece extraño. ¿No debería ser simplemente " env-> "?

Tal vez me equivoque y se supone que funciona, pero ¿por qué complicar las cosas de todos modos?


La principal diferencia entre las llamadas JNI en C y CPP es esta:

El JNI de estilo C se parece a (* env) -> SomeJNICall (env, param1 ...)

El estilo JNI de C ++ se parece a env-> SomeJNICall (param1 ...)

así que para convertirlo a CPP tienes que hacer

Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj) { jclass cls = env->GetObjectClass(obj); jmethodID mid = env->GetMethodID(cls, "callback", "()V"); if (mid == NULL) { return; /* method not found */ } printf("In C++/n"); env->CallVoidMethod(obj, mid); //rest of your code

Además, asegúrese de que sus funciones JNI siguen la convención de nomenclatura.

Ejemplo:

JNIEXPORT jint JNICALL Java_com_shark_JNITestLib_JNITestLib_startServer(JNIEnv* env, jobject o, jstring inputName, jstring streamName, jstring description) {

Puede ver que la convención es Java_ (nombre del paquete) _ (nombre de clase) _ (nombre de método)

ya que el anterior fue utilizado en una clase como

package com.shark.JNITestLib import java.util.stuff; public class JNITestLib { static { System.loadLibrary("myJNIlib"); } public native synchronized int startServer(String inputName, String streamName, String description); //more class stuff... }

Cuando trabajaba con JNI, era una convención nombrar a la clase que contenía llamadas JNI para que tuviera el mismo nombre que el paquete. Es por eso que ves JNITestLib dos veces (y es por eso que mi JNI funciona desde el principio porque siempre olvido cómo nombrar correctamente las llamadas JNI)

Saludos, espero haberte ayudado :)


Solía ​​tener el libro Essential JNI . Y aunque está un poco anticuado, gran parte todavía funciona hoy.

Si recuerdo correctamente, en C, las construcciones de Java son simplemente punteros. Por lo tanto, en su código, " (*env)-> " es la eliminación de referencias a los punteros para darle acceso a los métodos subyacentes.

Para C ++, " env " es en realidad un objeto, una entidad diferente a un puntero C. (Y JNI puede proporcionar objetos reales para que su código C ++ pueda manipularlos, ya que C ++ en realidad admite objetos.) Por lo tanto, " env-> " tiene un significado diferente en C ++, significa "llamar al método contenido en el objeto al que apunta " env ".

La otra diferencia, creo, es que muchas de las funciones C-JNI requieren que uno de sus parámetros sea el " JNIEnv *env ". Así que en C puede que tengas que decir (*env)->foo(env, bar) . Con c ++, la segunda referencia a " env " no es necesaria, por lo que puede decir " env->foo(bar) "

Desafortunadamente, no tengo el libro anterior frente a mí, ¡así que no puedo confirmar esto! Pero creo que investigar esas dos cosas (específicamente buscarlas en google o en otro código JNI) te llevará bastante lejos.