Newsgroup: it.comp.java
Titolo: JNI - caricare le librerie

Salve a tutti,
devi interfacciare un programma Java con delle funzioni C ed essendo la
prima volta che lo faccio sono partito da una cosa semplice.
File C:
#include <jni.h>
#include <stdio.h>
#include "Functions.h"
JNIEXPORT jint JNICALL Java_Functions_prova
  (JNIEnv *env, jobject obj) {
        printf("prova\n");
        return 0;
}
questo è il file C con la sola funzione prova, compilato su Linux con gcc
nella libreria libFunctions.so. Ho copiato scrupolosamente la riga di
comando che ho trovato su un libro e la compilazione non ha dato problemi.
Ora la classe Java:
public class Functions {
  static {
    String dir = System.getProperty("user.dir");
    String libdir = dir.concat("/Cfiles/libFunctions.so");
    System.load(libdir);
  }
  public static native int prova();
}
Piu' semplice di così non si puo', eppure non funziona. Il path contenuto in
libdir è proprio quello del file libFunctions.so ma da il seguente errore:
java.lang.UnsatisfiedLinkError: prova
Ho notato che quando metto un path diverso mi da un altro errore dicendo che
non trova il file. Da questo devo dedurre che lo trova ma che il mio file
ha qualcosa che non va?
Ho anche provato a mettere la libreria in una directory nel
java.library.path o come si chiama ma mi da lo stesso messaggio di errore.
Perché?
Grazie
Matteo

Prova ad usare solo:
try {
  System.loadLibrary("Functions");
} catch (UnsatisfiedLinkError e) {
  e.printStackTrace();
}
Il ".so" e "lib" vengono aggiunti in automatico dal metodo. Ultimo
accorgimento, imposta la variabile d'ambiente LD_LIBRARY_PATH con il
percorso dove hai messo la "libFunctions.so". Es:
  export LD_LIBRARY_PATH=/home/matish/lib
Ciao,
Marco
-- 
//\/\ Marco (LM) Lamberto (
marcol...@despammed.com
)
      SIForge.org     -  
http://www.siforge.org/
      The Sunny Spot  -  
http://the.sunnyspot.org/

 }
Ho provato ma non funziona... Ho anche provato a mettere il file in una
delle cartelle del java.library.path ma niente.
Comunque tornando al System.load(filename) perché non funziona se il path è
giusto ed il file sta proprio li?
persino:
String libpath = <path di libFunctions.so>;
System.out.println(new File(libpath).exists());
mi stampa true!
non capisco...
Grazie
Matteo

 delle cartelle del java.library.path ma niente.
[...]
Controlla sull'api reference di Java, load e loadLibrary NON sono la
stessa cosa, o meglio si aspettano argomenti leggermente diversi:
public void load(String filename)
  Loads the specified filename as a dynamic library. The filename argument
  must be a complete path name. From java_g it will automagically insert
  "_g" before the ".so" (for example
  Runtime.getRuntime().load("/home/avh/lib/libX11.so");).
  This is similar to the method loadLibrary(String), but it accepts a
  general file name as an argument rather than just a library name,
  allowing any file of native code to be loaded.
public void loadLibrary(String libname)
  Loads the dynamic library with the specified library name. A file
  containing native code is loaded from the local file system from a place
  where library files are conventionally obtained. The details of this
  process are implementation-dependent. The mapping from a library name to
  a specific filename is done in a system-specific manner.
Spero d'esserti stato piu` utile! ;)


   Runtime.getRuntime().load("/home/avh/lib/libX11.so");).
l'avevo letto, ed infatti quello che ho provato é:
System.load("/home/matish/eccetera/libFunctions.so");
il path è corretto ma non va...
Qualcuno è riuscito a farlo funionare?
Grazie comunque ;)
Matteo

 Qualcuno č riuscito a farlo funionare?
Dunque, per quello che mi riguarda ho sempre usato loadLibrary (che usa
"load") ed ha sempre funzionato, sotto Linux ed anche Windows.
A questo punto mi viene un piccolo dubbio, sei sicuro che la tua
libFunctions.so sia compilata correttamente come shared library? Non e`
che per caso hai fatto uno strip dei simboli??


 che per caso hai fatto uno strip dei simboli??
Che cos'é uno strip dei simboli?
Comunque ormai sono quasi sicuro che il problema sia nella compilazione.
Eppure ho usato le seguenti righe:
prompt> gcc -c  -fPIC -I/usr/local/Java/j2sdk_nb/j2sdk1.4.2/include/
-I/usr/local/Java/j2sdk_nb/j2sdk1.4.2/include/linux/  Functions.c
prompt>gcc -shared -o libFunctions.so Functions.o
copiate da "Java2 tecniche avanzate"
(tanto avanzate che non si riescono ad usare :)
Non è che hai a portata di mano le righe di comando che hai usato tu...
Grazie!
Matteo


si', l'errore dice che non trova la funzione prova, se non trovasse la
libreria ne darebbe un altro.
Normalmente questi problemi saltano fuori con le differenti decorazioni
che vengono date al nome della funzione dal compilatore, ad es.:
prova diventa _prova oppure _prova@8 ... dovrestiriuscire a capirlo
visualizzando i nomi dei simboli della libreria.
A JNI piacciono (almeno in Windows) nella forma _prova@8
prova a seguire le istruzioni di compilazione che ci sono sul tutorial
della sun
http://java.sun.com/docs/books/tutorial/native1.1/stepbystep/step5.html
ciao
-- 
Seti@Home Java Applets
http://maruko.webhop.net/

della sun
io in Linux ho fatto una roba del genere:
gcc -O2 -shared -Wl,-soname,libProva.so -I/opt/j2sdk1.4.1_01/include
-I/opt/j2sdk1.4.1_01/include/linux -o libProva.so prova.c -static -lc
ora non ricordo con precisione cosa significa ogni opzione ma man gg
dovrebbe aiutarti.


matish wrote:
Ce l'ho fatta!!!!!!!!!!!!!!
grazie a tutti e due :))
Vi scrivo la "soluzione" perché qualcuno puo' incappare nel mio stesso
errore:
avevo chiamato l'utility javah dalla directory che conteneva il file
Functions.class, ma la classe Functions era dichiarata in un package.
Quando ho copiato il codice della classe ho omesso le prima riga (porca
miseria) e quindi nessuno (me incluso) si era accorto che il nome della
funzione generata era
Java_Functions_prova
mentre doveva essere:
Java_PACKAGE_Functions_prova
Invocando javah dalla directory principale (dell'applicazione) ed usando 
javah package.Functions
invece di semplicemente
javah Functions
il file generato aveva il nome della funzione corretta.
Meno male... :)
Ciao
Matteo

 Non è che hai a portata di mano le righe di comando che hai usato tu...
Sono praticamente le stesse che hai usato tu.


 Meno male... :)
Gia`!! Meno male!! ;)
Ciao,
Marco
