2011-09-24 38 views
10

Tôi đang sử dụng JNI để chuyển dữ liệu giữa C++ và Java. Tôi cần phải vượt qua một 'dài' loại, và đang làm như vậy sử dụng một cái gì đó như:Đúc loại C++ dài thành JNI jlong ​​

long myLongVal = 100; 
jlong val = (jlong)myLongVal; 
CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val); 

Tuy nhiên trong Java, khi tham số 'dài' được lấy ra, nó được lấy ra như một số số âm rất lớn. Tôi đang làm gì sai?

+2

'long! = Jlong' có thể? – quasiverse

+0

Thật kỳ lạ, Java tiếp tục nhận được 4294967297 khi tôi thông qua nó một giá trị "1" thông qua JNI. Con số đó là một số Fermat. Có vẻ như một giá trị ngẫu nhiên khủng khiếp. Nếu bất cứ ai có bất kỳ ý tưởng nào về lý do tại sao giá trị cụ thể này được nhìn thấy, tôi muốn được nghe nó. Quay lại chủ đề, hãy gán giá trị '(jlong) dài của tôi cho phép Java/JNI phân tích cú pháp thành giá trị chính xác của 1. – StockB

+1

4294967297 là (1 << 32) + 1 – samgak

Trả lời

12

Khi bạn vượt qua một jlong ​​(64 bit) làm con trỏ (rất có thể, 32-bit), bạn nhất thiết phải mất dữ liệu. Tôi không chắc chắn quy ước là gì, nhưng thử một trong hai điều này:

CallStaticVoidMethodA(myClass, "(J)V", (jvalue*)&val); //Note address-of! 

hay này:

CallStaticVoidMethod(myClass, "(J)V", val); 

Đó là ...A phương pháp mà phải mất một mảng jvalue, các phương pháp không postfix mất C tương đương với vô hướng Các loại Java.

Đoạn đầu tiên có phần không an toàn; một tốt hơn, nếu tiết hơn, thay thế sẽ là:

jvalue jv; 
jv.j = val; 
CallStaticVoidMethodA(myClass, "(J)V", &jv); 

Trên một số archtectures CPU kỳ lạ, các yêu cầu liên kết cho jlong biến và jvalue đoàn thể có thể khác. Khi bạn khai báo một liên minh một cách rõ ràng, trình biên dịch sẽ xử lý điều đó.

Cũng lưu ý rằng C++ long kiểu dữ liệu thường là 32 bit. jlong ​​là 64 bit, trên nền tảng 32 bit tương đương C không chuẩn là long long hoặc __int64.

+3

" C++ dài là 32 bit "- -true trên một số kiến ​​trúc, chứ không phải trên các kiến ​​trúc khác. Linux x64 thường sử dụng dài 64 bit. lâu dài không có sẵn ở khắp mọi nơi (đó là phần mở rộng IIRC). –

+1

Đúng vậy. Tôi sẽ thêm một bằng cấp. –

+0

Cảm ơn câu trả lời của bạn - tiếc là tôi đã thử cả hai phương pháp tiếp cận suggseted và tham số vẫn xuất hiện bị cắt xén khi truy xuất trong Java, tôi cũng đã thử với các loại int và float ngoài dài: (Kỳ lạ sau * * làm việc, và chỉ cho int loại (mặc dù nó không có ý nghĩa) 'int someInt = 100; CallStaticVoidMethod (myClass," (I) V ", (jvalue *) (jint) someInt);' –

3
CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val); 

Đây là hành vi không xác định. Bạn đang truyền một số nguyên làm con trỏ. Nó không phải là một con trỏ. Bạn cần, ít nhất, để vượt qua địa chỉ . Mã này sẽ trên hầu hết các nền tảng ngay lập tức sụp đổ.

+0

bạn hoàn toàn đúng - tôi nên lấy địa chỉ, tuy nhiên điều này vẫn không hiệu quả đối với tôi (bất kể trôi nổi, int hoặc dài loại, như tôi đã thử tất cả những điều này). Kỳ lạ, các công trình sau đây, và chỉ cho các loại int (mặc dù nó không có ý nghĩa gì) 'int someInt = 100; CallStaticVoidMethod (myClass," (I) V " , (jvalue *) (jint) someInt) ; ' –