Newsgroup: it.comp.java
Titolo: GetStringUTFChars,NewStringUTF

Sto creando una DLL che permetta l'interfacciamento tra linguaggio C e
linguaggio java.
Classe HelloWorld.java:
class HelloWorld {
    public static native String displayHelloWorld(String comando);
    private static String pippo;
    static {
        System.loadLibrary("hello");
    }
    public static void main(String[] args) {
    pippo=displayHelloWorld("ciao");
 System.out.println("Strumento: " + pippo);
    }
}
Firma del metodo displayHelloWorld, riportata nel file HelloWorld.h generato
con javah -jni :
JNIEXPORT jstring JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *,
jclass,jstring)
Programma in linguaggio C++ prova.cpp da cui creare la DLL:
1 #include "HelloWorld.h"
2 #include <stdio.h>
3
4 static char risposta[32];
5 const char* Ccomando;
6 JNIEXPORT jstring JNICALL Java_HelloWorld_displayHelloWorld
7 (JNIEnv *env, jclass c,jstring comando)
8 {
9 Ccomando = (*env)->GetStringUTFChars(env,comando,NULL);
10 sprintf(risposta,Ccomando);
11 (*env)->ReleaseStringUTFChars(env,comando,Ccomando);
12 return (*env)->NewStringUTF(env,risposta);
13 }
A questo punto ho digtato dal prompt del dos :
vcvars32.bat
e poi
cl -Ic:\jdk1.1-beta\include -ic:\jdk1.1-beta\include\win32 -LD
prova.cpp -FeHelloWorld.dll
Ma ottengo i seguenti errori:
prova.cpp(9) : error C2819: type 'JNIEnv_' does not have an overloaded
member 'operator ->'
prova.cpp(9) : error C2227: left of '->GetStringUTFChar' must point to
class/struct/union
prova.cpp(11) : error C2819: type 'JNIEnv_' does not have an overloaded
member 'operator ->'
prova.cpp(11) : error C2227: left of '->ReleaseStringUTFChar' must point to
class/struct/union
prova.cpp(12) : error C2819: type 'JNIEnv_' does not have an overloaded
member 'operator ->'
prova.cpp(12) : error C2227: left of '->NewStringUTF' must point to
class/struct/union
Cosa ci può essere che non va?
Non vengono riconosciute le funzioni NewStringUTF, ReleaseStringUTFChar e
GetStringUTFChar?
Grazie a tutti, ed in particolare a Cristiano Sadun,
ciao,
Fernando.

[...]
"env" e' dichiarato JNIEnv *, cioe' un puntatore a un oggetto di classe
JNIEnv: quindi per referenziarne il contenuto o usi "(*env)." oppure
"env->" "X->" e' un'abbreviazione per "(*X).", quindi con con (*env)->
dici al compilatore di prendere il puntatore env, prenderne il contenuto
(*env), e _poi_ prendere il contenuto di quel che viene fuori ancora una
volta: ovviamente il compilatore si incavola. :-) 
La sintassi corretta' e' env->GetStringUTFChar(...) etc.
Inoltre, stai includendo <jni.h>? (devi avere nell'include path sia
<java_home>\include che <java_home>\include\win32). 
-- 
Life's something u don't get out alive..
ObjectZone - 
http://space.tin.it/computer/csadun

La sintassi corretta' e' env->GetStringUTFChar(...) etc.
alla Sun dicono
http://java.sun.com/docs/books/tutorial/native1.1/implementing/string.html
-- 
Ciao
	Fabrizio C.

Fabrizio wrote:
"La sintassi corretta e' env->GetStringUTFChar(...) etc."
OK, infatti con quella sintassi a me il compilatore non da errori relativi a
"*" e "->", ma allora perché la sun nel sito
http://java.sun.com/docs/books/tutorial/native1.1/implementing/string.html
utilizza la porzione di codice contenente
(*env)->GetStringUTFChar(...)...????
Per fare un esempio ho modellato il mio programma C++ sulla base di quello
riportato nel tutorial:
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *env,jclass c,jstring comando)
{
 const char *Ccomando = (*env)->GetStringUTFChars(env,comando,0);
 (*env)->ReleaseStringUTFChars(env,comando,Ccomando);
    return (*env)->NewStringUTF(env,comando);
}
Ecco gli errori:
error C2819: type 'JNIEnv_' does not have an overloaded member 'operator ->'
error C2227: left of '->GetStringUTFChars' must point to class/struct/union
error C2819: type 'JNIEnv_' does not have an overloaded member 'operator ->'
error C2227: left of '->ReleaseStringUTFChars' must point to
class/struct/union
error C2819: type 'JNIEnv_' does not have an overloaded member 'operator ->'
error C2227: left of '->NewStringUTF' must point to class/struct/union
Se invece cambio la sintassi dello stesso programma in:
env->GetStringUTFChars(...)...:
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *env,jclass c,jstring comando)
{
 const char *Ccomando = env->GetStringUTFChars(env,comando,0);
 env->ReleaseStringUTFChars(env,comando,Ccomando);
    return env->NewStringUTF(env,comando);
}
Gli errori sono:
error C2660: 'GetStringUTFChars' : function does not take 3 parameters
error C2660: 'ReleaseStringUTFChars' : function does not take 3 parameters
error C2664: 'NewStringUTF' : cannot convert parameter 1 from 'struct
JNIEnv_ *' to 'const char *'
Se ad esempio per eliminare il primo errore tolgo il 3° argomento della
funzione GetStringUTFChars()
compare un nuovo errore:
error C2664: 'GetStringUTFChars' : cannot convert parameter 2 from 'void *'
to 'unsigned char *'
E'  un vero disastro!!!
Se qualcuno vuol fare una prova, riporto di seguito la classe
HelloWorld.java (completamente diversa da quella realizzata dalla sun per i
suoi esempi) che contiene il metodo nativo displayHelloWorld :
class HelloWorld {
    public static native String displayHelloWorld(String comando);
    private static String pippo;
    static {
        System.loadLibrary("hello");
    }
    public static void main(String[] args) {
    pippo=displayHelloWorld("ciao");
 System.out.println("Strumento: " + pippo);
    }
}
Da questa, come saprete meglio di me,  con javah -jni bisogna creare il file
HelloWorld.h, etc, etc.....

(*env)->GetStringUTFChar(...)...????
[CUT]
Mi rigiri la domanda? L'indirizzo te l'ho mandato io.
Il mio suggerimento (implicito) era quello di provare a fare girare
l'esempio della Sun ESATTAMENTE come riportato sul Tutorial.
Io non l'ho mai provato, ma non ho motivo di credere che non funzioni.
Così potresti iniziare a capire se il problema è il codice o i tuoi
strumenti.
Mi dispiace, ma non posso aiutarti di più per mancanza di esperienza
specifica.
Una cosa però puoi dire (utile ad altri che ti possono aiutare): con
quale versione di Java (e di JNI) stai lavorando?
-- 
Ciao
	Fabrizio C.

'struct JNIEnv_ *' to 'const char *'
Questi sono errori normali. :-)
Ancora, se usi C++ (e questa e' la comodita' di cui sopra) *non* devi
passare l'environment come primo argomento (i motivi sono semplici,
ma fuori dallo scope di questa risposta :). Nella documentazione hanno
scritto solo i prototipi C, ma basta togliere il primo JNIEnv *
per ottenere il corrispondente C++.
Quindi, in C++, per usare GetStringUTFChars, (il cui prototipo nella
documentazione che ho qui, JNI1.1 specs, e' 
const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean
*isCopy); 
elimini il primo JNIEnv * e quindi vedi il metodo come
const char* GetStringUTFChars(jstring string, jboolean *isCopy);
(in C++, le funzioni JNI sono metodi della struttura JNIEnv. Occhio che
una struttura C++ e' leggermente diversa da struttura C).
Quindi la tua chiamata sara' 
    	env->GetStringUTFChars(comando,0);
Voila'. Stessa cosa con tutte le altre funzioni JNI.
Il tuo errore stava nel togliere il terzo argomento e non il primo (e, di
fondo, nel non leggere i tipi: ti salvi giorni di lavoro se solo dai
un'occhiata ai prototipi della funzione e a <jni.h> ;-).
