2010-07-30 3 views
5

Estoy definiendo una clase Java de C con la llamada JNI DefineClass() y luego registro las devoluciones de llamada nativas para los métodos en la clase que son nativo. La clase tiene dos métodos estáticos, ambos son nativos. Yo uso RegisterNatives() para registrar las funciones nativas. Ambas llamadas tienen éxito.Estoy definiendo una clase Java de C con DefineClass() pero obtengo UnsatisfiedLinkError

Pero cuando me refiero a estos métodos nativos de mi código Java me sale java.lang.UnsatisfiedLinkError myPackage.myClass.myMethod (I) V

Pero sé que defineClass devuelve un objeto de clase para myPackage.myClass y yo sepa que myMethod (I) V ha sido registrado como un método en esa clase.

Recibo esta falla justo cuando está a punto de ejecutar main() - donde la llamada a mi método nativo es (por el momento, para probar).

Como prueba, intenté llamar a DefineClass dos veces en el mismo JNIEnv para ver qué sucedía. Obtengo un error de definición de clase duplicado. También intenté llamar a FindClass() después de definirlo y JNIEnv devuelve una referencia a la clase definida.

Por lo tanto, estoy definitivamente creando la clase dinámicamente, pero falla cuando trato de referirme a sus métodos.

¿Alguna idea? Toda la entrada apreciada.

Plataforma: Windows, código de 32 bits en 64 bit XP.

+0

¿Podría tener una versión anterior de su dll en algún lugar de su camino? –

+0

Cuando compiló su DLL ¿exportó las funciones? –

+0

Romain: no es necesario exportar mis funciones y la versión de DLL es irrelevante: la DLL que registra las funciones con RegisterNatives() es la DLL que proporciona las funciones. Las funciones están, por definición, disponibles en el momento en que se llama a RegisterNatives(). –

Respuesta

2

Parece que no puede definir un método nativo utilizando DefineClass() y llama a ese método nativo directamente desde su código inyectado. Tienes que tener un método de trampolín en tu clase inyectada (en forma de códigos de bytes Java) que luego llama a tus métodos nativos. Solo entonces funcionará. Me llevó tres días resolverlo.

Otro problema es asegurarse de que su código inyectado sea válido. El código que estaba tratando parecía válido, pero en una inspección más cercana estaba sacando una constante de 4 bytes del conjunto constante como un operando para una instrucción de 8 bytes. Entonces eso falló el verificador. Una vez que se arregló eso (y el trampolín nativo), todo funcionó.

Sin embargo, para llegar a través de todas las permutaciones que tuve que probar tomó 3 días. Me sentí bien cuando funcionaba.

¿Cómo hacer el trampolín? Vea los ejemplos (en C) que se envían con el SDK de Java. Son bastante largos y no apropiados para publicar aquí.

Cuestiones relacionadas