Estreno esta nueva sección java dentro del blog hablando sobre un tema que parece haber resurgido de las cenizas, ni más ni menos que el uso de la tecnología JNI de Java. Para los no iniciados, decir que JNI es: Java Native Interface, y que sirve para integrar una aplicación java con código en C/C++. Podéis descargaros The Java Native Interface, Programmer’s Guide and Specification desde la web de Sun Microsystems y ver más cosas sobre dicha tecnología.
La misión en mi caso era sencilla, montar el típico ejemplo para ver como funciona JNI y como quería probar Code::Blocks, decidí buscar un artículo y probar suerte. Increiblemente no conseguía hacer funcionar el ejemplo más sencillo que puedes imaginar, y sin embargo todo el mundo lo hacía funcionar más o menos rápido. Desesperado por la falta de habilidad aparente, me dirigí a la web de Sun y me descarge el manual que os he comentado, y como podéis ver, dedica su capítulo 2 a hacer funcionar el ejemplo, así que me dispuse a seguir paso a paso el procedimiento como si de una receta se tratase.
Incluso la parte de java la hice con bloc de notas en mano, nada de Eclipse y haciendo copy&paste del código, para no decirme a mi mismo que me había equivocado. El misterio empezó a desvelarse, cuando llegué a la parte de compilación del código en C para obtener la DLL. Dicho manual utiliza Microsoft Visual C++ como compilador, ahí fue donde empezé a dudar de lo que yo había hecho con Code::Blocks. Cuando terminé el ejemplo, todo funcionaba, incluso logré hacer funcionar todo con lo que había montado en entorno Eclipse y con mis clases iniciales. Sin embargo aunque para este ejemplo disponía de Visual C++, no era mi intención seguir utilizándolo, y pensé en buscar la clave a porqué con Code::Blocks no había sido capaz de lograr la hazaña.
En principio, ya había buscado en google cosas sobre jni y Code::Blocks pero no creí que el fallo fuese el último sino mi inexperiencia con dicha tecnología. Localizado el error, decidí hacer búsquedas más concretas. Resulta que en un foro de dicho software, se encuentra la respuesta: Code::Blocks no produce una buena DLL sino que cambia el nombre de los métodos, por lo que luego no son accesibles desde java por que los nombres a los que hacemos referencia han cambiado. Fuente.
En este mismo hilo viene como se obtiene la solución. Tenemos que recurrir a la línea de comandos y generar la librería dinámica desde este entorno. Sin embargo si haces lo que en el foro se dice, la solución que un tal Michael da, no obtendrás el éxito que esperabas, así que tuve que seguir buscando. El procedimiento a seguir es algo así como:
- Para compilar el código C que tenemos:
gcc -c HelloWorld.c
- Para obtener el fichero de definición necesario para la generación de la DLL:
dlltool -z HelloWorld.def HelloWorld.o
- En este punto viene nuestra intervención manual, este fichero generado es incorrecto, al editarlo os daréis cuenta que los nombres de los métodos han cambiado y por ejemplo nuestro método antes: Java_HelloWorld_print ha pasado a Java_HelloWorld_print@8 @ 1, he aquí el error!!!!. Por eso nuestras clases Java nos dan el error de que no pueden encontrar el método en cuestión. Osea, que no es Code::Blocks quien tiene el error sino el compilador gcc que no es capaz de generar bien este archivo, que es necesario para generar la DLL. La solución pasa por editar esto a mano y eliminar los caracteres extraños y luego ejecutar:
gcc -shared -o HelloWorld.dll HelloWorld.o HelloWorld.def
Esta DLL ya si es funcional y operativa, tanto como la de Visual C++.
Si por algún casual probáis:
gcc -shared -o HelloWorld.dll HelloWorld.o
Veréis que os genera la DLL sin necesidad de necesitar el .def, sin embargo si váis a comprobarlo, podréis ratificar que dicha DLL tampoco es buena. Supongo que en este punto gcc evita el segundo paso y se genera un .def que utiliza internamente.
Comprobado esto, podemos seguir utilizando Code::Blocks que sin duda es Open Source por si alguno lo dudábais.

Hola.
He leído que poniendo en gcc la opción –add-stdcall-alias se soluciona el problema.
Un saludo.