Melarikan diri dari string Java untuk kode JNI

Saya memiliki literal string Java dengan karakter Unicode yang perlu ditransfer ke literal string C, yang dapat dimuat dengan JNIEnv.NewString.

Sayangnya, metode di atas membutuhkan pointer ke array unsigned short (jchar). Saya sudah mencoba menggunakan kode seperti berikut:

unsigned short str[] = {65, 66, 67};
jstring java_str = (*env)->NewString(env, str, 3);

Namun, hal ini memerlukan banyak ruang, tidak dapat dibaca manusia, dan sulit dipelihara.

Apakah ada cara untuk mengubah string literal menjadi unsigned short[] di C, sambil tetap dapat menggunakan karakter UTF-16 Java?

Bisakah pelolosan ini dilakukan secara terprogram? yaitu mengubah java.lang.String menjadi string literal yang dapat berfungsi dalam kode sumber C.


person konsolas    schedule 25.02.2017    source sumber
comment
C memang memiliki string yang lebar, sayangnya implementasinya menentukan rangkaian karakter apa yang mereka gunakan, kecuali jika Anda dapat menggunakan C11   -  person Antti Haapala    schedule 25.02.2017
comment
Literal string C bersifat hanya baca. Tetapi apakah Anda mencoba membuat kode sumber C?   -  person Weather Vane    schedule 25.02.2017
comment
Saya pada dasarnya lebih suka tidak melepaskan banyak string secara manual, jadi akan lebih baik jika menghasilkan literal. Jika itu tidak memungkinkan, saya dapat menghindarinya secara manual.   -  person konsolas    schedule 25.02.2017


Jawaban (2)


Jika Anda bisa menggunakan C11, dan GCC, Anda bisa menggunakan char16_t baru yang akan menjadi UTF-16 di GCC:

#include <uchar.h>

#ifndef __STDC_UTF_16__
#error "char16_t not UTF-16"
#endif

...
    char16_t my_string[] = u"abc";
    jstring java_str = (*env)->NewString(env, str, 3);

Dan kompilasi dengan gcc -std=c11

Namun, sebagian besar waktu seseorang hanya menggunakan string ASCII dan untuk itu seseorang cukup menggunakan string ASCII

jstring java_str = (*env)->NewStringUTF(env, "abc");

yang akan berasumsi bahwa string tersebut berada dalam pengkodean UTF-8 yang dimodifikasi (yaitu pasangan pengganti UTF-16 dikodekan secara terpisah ke dalam UTF-8; dan diakhiri dengan null). Karena ASCII adalah bagian dari UTF-8, ini lebih dapat digunakan untuk string ASCII.

person Antti Haapala    schedule 25.02.2017
comment
Ini adalah penggunaan NewStringUTF yang tepat dan bijaksana karena string adalah string literal dalam kode sumber dan dapat diketahui bahwa kompiler diberi tahu kumpulan karakter sumber yang benar dan kumpulan karakter eksekusi dapat dipilih agar kompatibel dengan UTF-8 yang dimodifikasi untuk rentang titik kode tertentu (termasuk U+0000 hingga D+D7FF). Disarankan untuk memberikan komentar kode sumber mengenai hal tersebut. Kumpulan rangkaian karakter yang berlaku bahkan lebih besar jika data Anda terbatas pada Kontrol C0 dan Latin Dasar (U+0000 hingga U+007F). - person Tom Blodget; 26.02.2017
comment
Format literal string C11 ini sepertinya yang saya cari. Terima kasih! - person konsolas; 26.02.2017

Apa yang Anda cari tidak disebut melarikan diri.

Tampaknya yang ingin Anda lakukan adalah menentukan string karakter di C, menggunakan literal string yang dapat dibaca manusia, dan meneruskannya ke JNI NewString().

Anda harus membaca di wchar_t.

Lihat Apa yang dimaksud dengan string karakter lebar dalam bahasa C? dan https://en.wikibooks.org/wiki/C_Programming/C_Reference/wchar.h

Apa yang perlu Anda lakukan adalah mendefinisikan literal string Anda sebagai wchar_t (menggunakan notasi "L" yang dijelaskan dalam posting di atas) dan kemudian menulis fungsi konversi yang mengubah array wchar_t ini menjadi array jchar.

Sayangnya, standar C tidak menentukan implementasi yang tepat dari wchar_t, dan malah menyerahkannya kepada vendor kompiler C untuk melakukan apa pun yang mereka inginkan, sehingga ada kemungkinan kompiler C Anda tidak memperlakukan wchar_t sebagai kuantitas 16-bit. Dalam hal ini, fungsi konversi Anda tidak akan bisa begitu saja memasukkan array wchar_t ke array jchar, dan sebagai gantinya harus mengonversinya satu per satu. Ini sedikit merepotkan, tapi bisa dilakukan. Semoga beruntung!

person Mike Nakis    schedule 25.02.2017