การหลีกเลี่ยงสตริง Java สำหรับโค้ด JNI

ฉันมีตัวอักษรสตริง Java ที่มีอักขระ Unicode ที่ต้องถ่ายโอนไปยังตัวอักษรสตริง C ซึ่งสามารถโหลดได้ด้วย JNIEnv.NewString

น่าเสียดายที่วิธีการข้างต้นใช้ตัวชี้ไปยังอาร์เรย์ unsigned short (jchar) ฉันได้ลองใช้รหัสดังต่อไปนี้:

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

อย่างไรก็ตาม การดำเนินการนี้ต้องใช้พื้นที่มาก มนุษย์ไม่สามารถอ่านได้ และดูแลรักษาได้ยาก

มีวิธีแปลงสตริงตัวอักษรเป็น unsigned short[] ใน C ในขณะที่ยังสามารถใช้อักขระ UTF-16 ของ Java ได้หรือไม่

การหลบหนีนี้สามารถทำได้โดยทางโปรแกรมหรือไม่ เช่นแปลง java.lang.String เป็นตัวอักษรสตริงที่จะทำงานในซอร์สโค้ด C


person konsolas    schedule 25.02.2017    source แหล่งที่มา
comment
C มีสตริงที่กว้าง แต่น่าเสียดายที่เป็นการระบุว่ามีการใช้ชุดอักขระใด ยกเว้นว่าคุณสามารถใช้ C11 ได้   -  person Antti Haapala    schedule 25.02.2017
comment
ตัวอักษรสตริง AC เป็นแบบอ่านอย่างเดียว แต่คุณกำลังพยายามสร้างซอร์สโค้ด C หรือไม่?   -  person Weather Vane    schedule 25.02.2017
comment
โดยพื้นฐานแล้ว ฉันไม่ต้องการกำหนดสตริงจำนวนมากซ้ำด้วยตนเอง ดังนั้นจึงเป็นการดีที่จะสร้างตัวอักษร หากเป็นไปไม่ได้ ฉันสามารถหลบหนีด้วยตนเองได้   -  person konsolas    schedule 25.02.2017


คำตอบ (2)


หากคุณสามารถใช้ C11 และ GCC คุณสามารถใช้ char16_t ใหม่ซึ่งจะเป็น UTF-16 ใน 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);

และคอมไพล์ด้วย gcc -std=c11

แต่อย่างไรก็ตาม โดยส่วนใหญ่แล้วเราใช้เพียงสตริง ASCII และสำหรับสิ่งนั้นก็สามารถใช้

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

ซึ่งจะถือว่าสตริงอยู่ในการเข้ารหัส UTF-8 ที่ได้รับการแก้ไข (เช่น คู่ตัวแทน UTF-16 จะถูกเข้ารหัสแยกกันเป็น UTF-8 และสิ้นสุดด้วยค่า null) เนื่องจาก ASCII เป็นส่วนย่อยของ UTF-8 จึงค่อนข้างใช้ได้กับสตริง ASCII

person Antti Haapala    schedule 25.02.2017
comment
นี่เป็นการใช้ NewStringUTF อย่างเหมาะสมและสะดวก เนื่องจากสตริงเป็นสตริงตัวอักษรในซอร์สโค้ด และเป็นที่รู้กันว่าคอมไพเลอร์ได้รับการบอกชุดอักขระต้นทางที่ถูกต้อง และชุดอักขระเรียกใช้งานสามารถเลือกให้เข้ากันได้กับ UTF-8 ที่แก้ไขแล้วสำหรับ ช่วงโค้ดพอยต์บางช่วง (รวมถึง U+0000 ถึง D+D7FF) แนะนำให้แสดงความคิดเห็นเกี่ยวกับซอร์สโค้ดเกี่ยวกับเอฟเฟกต์นั้น ชุดของชุดอักขระที่ใช้ได้จะมีขนาดใหญ่กว่านี้หากข้อมูลของคุณถูกจำกัดไว้ที่ตัวควบคุม C0 และภาษาละตินพื้นฐาน (U+0000 ถึง U+007F) - person Tom Blodget; 26.02.2017
comment
รูปแบบตัวอักษรสตริง C11 นี้น่าจะเป็นสิ่งที่ฉันกำลังมองหา ขอบคุณ! - person konsolas; 26.02.2017

สิ่งที่คุณกำลังมองหาไม่เรียกว่าการหลบหนี

ดูเหมือนว่าสิ่งที่คุณต้องการทำคือระบุสตริงอักขระในภาษา C โดยใช้ลิเทอรัลสตริงที่มนุษย์สามารถอ่านได้ และสามารถส่งต่อสิ่งนี้ไปยัง JNI NewString() ได้

คุณจะต้องอ่านต่อใน wchar_t

ดู สตริงอักขระแบบกว้างในภาษา C คืออะไร และ https://en.wikibooks.org/wiki/C_Programming/C_Reference/wchar.h

สิ่งที่คุณต้องทำคือกำหนดตัวอักษรสตริงของคุณเป็น wchar_t (โดยใช้สัญลักษณ์ "L" ที่อธิบายไว้ในบทความด้านบน) จากนั้นเขียนฟังก์ชันการแปลงซึ่งจะแปลงอาร์เรย์ wchar_t เหล่านี้เป็นอาร์เรย์ jchar

น่าเสียดายที่มาตรฐาน C ไม่ได้กำหนดการนำไปใช้อย่างแม่นยำของ wchar_t และปล่อยให้ผู้จำหน่ายคอมไพเลอร์ C ดำเนินการตามที่ต้องการแทน ดังนั้นจึงมีโอกาสที่คอมไพเลอร์ C ของคุณจะไม่ถือว่า wchar_t เป็นปริมาณ 16 บิต ในกรณีนี้ ฟังก์ชันการแปลงของคุณจะไม่สามารถแปลงอาร์เรย์ wchar_t เป็นอาร์เรย์ jchar ได้ง่ายๆ และจะต้องแปลงทีละรายการแทน ยุ่งยากนิดหน่อยแต่ก็ทำได้ ขอให้โชคดี!

person Mike Nakis    schedule 25.02.2017