Domanda

Sto scrivendo del codice JNI in C ++ per essere chiamato da un'applet su Windows XP. Sono stato in grado di eseguire correttamente l'applet e di avere caricato e chiamato la libreria JNI, arrivando persino a farlo chiamare funzioni in altre DLL. Ho funzionato impostando la variabile di ambiente di sistema PATH per includere la directory in cui si trovano tutte le mie DLL.

Quindi, il problema è che aggiungo un'altra chiamata che utilizza una nuova DLL esterna e improvvisamente durante il caricamento della libreria, viene generato un UnsatisfiedLinkError. Il messaggio è: "Impossibile trovare la procedura specificata". Questo non sembra essere un problema con una DLL dipendente mancante, perché posso rimuovere una DLL dipendente e ottenere un messaggio diverso sulla DLL dipendente mancante. Da quello che sono stato in grado di trovare online, sembra che questo messaggio significhi che un'implementazione della funzione Java nativa non sia presente nella DLL, ma è strano che funzioni bene senza questo ulteriore bit di codice.

Qualcuno sa cosa potrebbe causare questo? Che tipo di cose può dare un messaggio "Impossibile trovare la procedura specificata" per un UnsatisifedLinkError?

È stato utile?

Soluzione

Ho capito il problema. Questo è stato un doozy. Il messaggio " Impossibile trovare la procedura specificata " per UnsatisfiedLinkError indica che non è stata trovata una funzione nella dll di root o in una dll dipendente . La causa più probabile di ciò in una situazione JNI è che la funzione JNI nativa non viene esportata correttamente. Ma ciò può accadere apparentemente se viene caricata una DLL dipendente e in quella DLL manca una funzione richiesta dal suo genitore.

A titolo di esempio, abbiamo una libreria denominata input.dll. L'ordine di ricerca DLL deve sempre cercare prima nella directory dell'applicazione e infine nelle directory PATH. In passato, abbiamo sempre eseguito file eseguibili dalla stessa directory di input.dll. Tuttavia, esiste un altro input.dll nella directory di sistema di Windows (che si trova nel mezzo dell'ordine di ricerca DLL). Quindi, quando eseguo questo da un'applet Java, se includo il codice sopra descritto nell'applet, che causa il caricamento di input.dll, carica input.dll dalla directory di sistema. Poiché il nostro codice prevede determinate funzioni in input.dll che non sono presenti (poiché si tratta di una DLL diversa), il caricamento non riesce con un messaggio di errore relativo alle procedure mancanti. Non perché le funzioni JNI vengono esportate in modo errato, ma perché è stata caricata la DLL dipendente errata e non conteneva le funzioni previste.

Altri suggerimenti

È possibile che la DLL sia stata creata utilizzando C ++ (anziché C). a meno che tu non ti sia preso cura di fare un esterno sulla procedura, questa è una possibile ragione.

Prova a esportare tutte le funzioni dalla DLL. Se l'elenco include la tua funzione, allora sei a posto.

Di solito, quando si effettua il collegamento ad altre librerie, è necessario collegarsi al file .lib pertinente. Sembra che tu non stia facendo riferimento a tutti i file lib di cui hai bisogno. Controlla cosa non collega e assicurati di aggiungere la sua lib all'elenco per il linker.

Hai creato la nuova DLL esterna utilizzando la procedura JNI standard? Cioè, usando Java e così via? In tal caso, non sono sicuro di cosa sia sbagliato.

In caso contrario, la procedura che stai tentando di chiamare non è stata esportata (come indicato da anjanb). Sono a conoscenza di due modi per esportare funzioni: un elenco di esportazione separato e contrassegnare funzioni specifiche con __declspec (dllexport).

Impossibile accedere alla variabile nella DLL C ++ da un'app C contiene qualche informazione in più sull'argomento delle DLL.

Compila il tuo codice c ++ in modalità debug. Quindi inserire DebugBreak (); dichiarazione in cui si desidera iniziare il debug. Esegui il codice java. Quando viene rilevata l'istruzione DebugBreak (), verrà visualizzato un popup con un pulsante Debug su di esso. Cliccaci sopra. Dev Studio si aprirà con il programma in codice macchina. Passa due volte con il debugger e dovresti essere in grado di superare il tuo codice sorgente.

Se hai risolto tutti i problemi di programmazione nei manuali e negli esempi JNI ma stai ancora riscontrando lo stesso errore di procedura mancante, probabilmente il problema può essere nella variabile del tuo percorso. Procedi di seguito ed esegui di nuovo:

  1. Assicurati di aver impostato la variabile JAVA_HOME sulla tua cartella JDK (non JRE perché JRE non contiene l'intestazione jni) Esempio: Nel pannello delle impostazioni delle variabili di ambiente definire var: JAVA_HOME val: C: \ Programmi \ Java \ jdk1.7.0_11
  2. aggiungi % JAVA_HOME% \ bin alla tua variabile di percorso

Dopo aver eseguito questi passaggi, l'applicazione può trovare il nome della procedura jni e i collegamenti a JNI.dll nel modo giusto. Quindi, spero che non si verifichi più questo errore di procedura mancante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top