Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Umlaute bei JAVA nativ Interface

165 views
Skip to first unread message

Georg Feyersinger

unread,
Aug 2, 2001, 12:07:49 PM8/2/01
to
Hallo!

Wir nutzen für unsere Applikation das JAVA native Interface um zwischen JAVA
und C++ zu kommunizieren.

Die Applikation läuft auf nt 4.0 die JAVA Version ist:

java version "1.3.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_01)
Java HotSpot(TM) Client VM (build 1.3.0_01, mixed mode)

Zur Umwandlung der UNICOD Strings in JAVA auf C++ verwenden wir die methode:

const char *cText = env->GetStringUTFChars(parText, 0);

Für alle Strings funktioniert die Umsätzung auch, bis auf die Zeichen
äÄöÖüÜß. Für diese Zeichen werden die Strings äÃ"öÃ-üÃoeÃY übergeben.

Die Eingabe der Zeichen erfolgt in der JAVA Umgebeung und die Umsätzung in
C++ wie oben dargestellt.

Kennt jemand eine Lösung des Problems

Georg Feyersinger

Carsten Dumke

unread,
Aug 2, 2001, 6:05:52 PM8/2/01
to
petra.fe...@direkt.at (Georg Feyersinger) wrote in
<99676762...@hagakure.utanet.at>:
[Stringübergabe von Java an C++ via JNI]

> const char *cText = env->GetStringUTFChars(parText, 0);
>
> Für alle Strings funktioniert die Umsätzung auch, bis auf die
> Zeichen äÄöÖüÜß. Für diese Zeichen werden die Strings
> äÃ"öÃ-üÃoeÃY übergeben.

Was ebenfalls korrektes UTF-8 sein dürfte.

UTF-8: UCS Transformation Format, 8-bit form
UCS: Universal Character Set

(Java nutzt UCS-2 mit 16 bit - 2 Octets - pro Zeichen)

>
> Die Eingabe der Zeichen erfolgt in der JAVA Umgebeung und die
> Umsätzung in C++ wie oben dargestellt.
>
> Kennt jemand eine Lösung des Problems

Per Definition gibt es kein Problem :-)

Die C++-Anwendung soll vermutlich ISO8859-1 (bzw. -15) nutzen,
dazu müssen die Zeichen von UTF-8 in das gewünschte Format
konvertiert werden.

Referenzen:
* The Unicode Standard Version 3.0 (ISBN: 0-201-61633-5)
* libunicode-0.4.tar.gz: Bibliothek mit Funktionen
zur Konvertierung
--
ciao,

Carsten

Uwe Roland

unread,
Aug 3, 2001, 3:39:00 AM8/3/01
to
On Thu, 2 Aug 2001 18:07:49 +0200, "Georg Feyersinger"
<petra.fe...@direkt.at> wrote:

Hi Georg,

>Zur Umwandlung der UNICOD Strings in JAVA auf C++ verwenden wir die methode:

>
>const char *cText = env->GetStringUTFChars(parText, 0);

Statt einem String einfach ein byte-Array übergeben ...

String encoding = "8859_1";
byte[] parText = anyString.getBytes(encoding);

und dann entsprechend auslesen ...

char* cText = (*env)->GetByteArrayElements(env, parText, 0);

Dies funktioniert bei mir unter WinNt und Solaris ...


>
>Für alle Strings funktioniert die Umsätzung auch, bis auf die Zeichen
>äÄöÖüÜß. Für diese Zeichen werden die Strings äÃ"öÃ-üÃoeÃY übergeben.
>
>Die Eingabe der Zeichen erfolgt in der JAVA Umgebeung und die Umsätzung in
>C++ wie oben dargestellt.
>
>Kennt jemand eine Lösung des Problems
>
>Georg Feyersinger
>

CU Uwe

Markus Grossert

unread,
Aug 3, 2001, 7:43:25 AM8/3/01
to
Hallo Georg,

Dasselbe Problem hatte ich auch bei einer Anwendung und habe mich heute
angeregt durch
Deinen Thread an die Behebung gemacht, wobei ich bei Deja in schönster Weise
fündig wurde.

> Zur Umwandlung der UNICOD Strings in JAVA auf C++ verwenden wir die
methode:
>
> const char *cText = env->GetStringUTFChars(parText, 0);
>
> Für alle Strings funktioniert die Umsätzung auch, bis auf die Zeichen
> äÄöÖüÜß. Für diese Zeichen werden die Strings äÃ"öÃ-üÃoeÃY übergeben.

Man hat in JNI zwei Möglichkeiten einen jstring in eine char-Sequenz
umzuwandeln.

const jchar * GetStringChars(JNIEnv *env, jstring string,
jboolean *isCopy);

oder

const char* GetStringUTFChars(JNIEnv *env, jstring string,
jboolean *isCopy);

Bei ersterem bekommt man Unicode, d.h. zwei Bytes pro Zeichen. Wenn man das
Resultat direkt in eine char-Sequenz umwandeln würde, würde die Sequenz in
den
meisten Fällen sehr schnell abbrechen, da das zweite Byte meist \0 ist.

Bei der zweiten Variante hat man Glück, wenn man es nur mit ASCII zu tun
hat,
wenn jedoch bspw. Umlaute vorkommen, bekommt man wegen des verwendeten
UTF-8 Formats ungewünschte Zeichen, da die Zeichen mit Code > 0x07f in
mehrere
(2-4) Bytes zerlegt werden. Zum UTF-8 Format siehe

http://java.sun.com/products/jdk/1.2/docs/guide/jni/spec/types.doc.html#1654
2

So einfach bekommt man also mit beiden Alternativen nicht ans Ziel. Für
beide
muß man also noch selbst Hand anlegen.

Ich habe mich für Version 1 entschieden, da ich hierzu eine praktikable
Funktion
gefunden hatte (Dank an Deja).

Anbei der Code:

char * jstringToMbs(JNIEnv * env, jstring s) {
/* Obtain a C-copy of the Java string */
const jchar *str = env->GetStringChars(s, 0);
const jsize len = env->GetStringLength(s);

/* process the string into multi-byte form */
/* via null terminated unicode string */
wchar_t * temp = new wchar_t[len+1];
memcpy(temp, str, sizeof(wchar_t)*len);
temp[len] = 0;

/* Now we are done with str */
env->ReleaseStringChars(s, str);

// convert down to multi-byte form.
// do one character at a time to get around
// a BorlandC++ quirk in the wcstombs function
char * mbstr = new char [(MB_CUR_MAX*len+2)];
char *m = mbstr; wchar_t *w = temp;
for(; *w; ++w) {
int k = wctomb(m, *w);
if(k>0) m+=k;
}
*m = 0;
delete [] temp;
return mbstr;
}

Zur zweiten Alternative ein Lösungsansatz (schlimme Bit-Schieberei):

http://tsemba.tripod.com/utf/utf8-uni.html

Gruß, Markus.


0 new messages