Tôi có một biến chuỗi trong lớp Java của mình:
lớp công khai myclass {
tệp Chuỗi cuối cùng được bảo vệ;
myclass(Chuỗi f) {
tập tin = f;
}
quy trình void gốc công khaiFiles();
public static void main(String[] args) {
myclass mc = myclass mới(args[0]);
mc.processFiles();
}
}
Trong C++ tôi có:
JNIEXPORT void JNICALL Java_myclass_processFiles(JNIEnv *env, jobject obj) {
jclass baseClass = env->GetObjectClass(obj);
jfieldID fid = env->GetFieldID(baseClass, "file", "Ljava/lang/String;");
tên tệp jchar = env->GetCharField(baseClass, fid);
jstring fileFieldString = env->NewString(&filename, sizeof(filename));
const char *nativeFileString = env->GetStringUTFChars(fileFieldString, NULL);
printf("JNI: Đường dẫn tập tin: %s\n", localFileString);
env->ReleaseStringUTFChars(fileFieldString, localFileString);
}
đầu ra của tôi là:
JNI: Đường dẫn tệp: ??2
Tôi đang làm gì sai, không chuyển đổi chuỗi Java thành chuỗi char* một cách chính xác? Tôi cung cấp đường dẫn ~/Desktop/myfile làm đối số duy nhất, do đó có một giá trị trong args[0]. Suy nghĩ của tôi là sizeof(filename) sai, nhưng theo tôi biết thì không có lựa chọn nào khác.
Tôi đã thử điều này:JNI. Cách lấy chuỗi j từ jobject và chuyển đổi nó thành char*Nhưng khi tôi chuyển kết quả của GetObjectField() sang jstring, tôi gặp lỗi:
# Môi trường chạy thi hành Java đã phát hiện một lỗi nghiêm trọng:
#
# SIGSEGV (0xb) tại pc=0x00000001043111e8, pid=6191, tid=3591
#
# Phiên bản JRE: Java(TM) SE Runtime Environment (8.0_45-b14) (bản dựng 1.8.0_45-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.45-b02 chế độ hỗn hợp bsd-amd64 đã nén rất tiếc)
# Khung có vấn đề:
# V [libjvm.dylib+0x3111e8] jni_GetStringUTFChars+0x66
#
# Không thể ghi kết xuất lõi. Để bật tính năng kết xuất lõi, hãy thử "ulimit -c không giới hạn" trước khi khởi động lại Java.
Ngoài ra, đây chỉ là JNI và Java 8 trên OSX và không liên quan gì đến Android.
Cảm ơn.
Cập nhật: Tôi đã có thể nhờ một người bạn xem nó và làm cho nó hoạt động với:
jfieldID fid = env->GetFieldID(baseClass, "file", "Ljava/lang/String;");
jstring jstr = (jstring) env->GetObjectField(thiz, fid);
const char *nativeFileString = env->GetStringUTFChars(jstr, NULL);
printf("JNI: Đường dẫn tập tin: %s\n", localFileString);
bạn đang làm tên tệp jchar = env->GetCharField(baseClass, fid);
Nhưng fid
Đúng Ljava/lang/Chuỗi;
thay vào đó là các trường thuộc loại ký tự
. Vì vậy bạn nên sử dụng env->GetObjectField()
Nhận Sợi dây
, rồi thực hiện những gì liên kết đó nói.
Bạn cũng có thể thêm sau mỗi dòng env->ExceptionDescribe()
Để gỡ lỗi tốt hơn, để xem điều gì xảy ra khi gọi Nó có bị ném sau env không Ngoại lệ
(Đây chỉ là để gỡ lỗi, trong mã sản xuất thực tế, bạn nên làm điều này mỗi lần env
Kiểm tra các trường hợp ngoại lệ sau cuộc gọi và thực hiện hành động nếu xảy ra sự cố).
BTW, có thể mã của bạn chỉ là ví dụ, nhưng nếu đó là mã thực của bạn thì nó sẽ tự nhiên
Phương thức được khai báo là tĩnh
và chỉ truyền chuỗi làm tham số.
Tôi là một lập trình viên xuất sắc, rất giỏi!