2011-12-15 5 views
5

Tôi có một dự án Android (nhắm mục tiêu Android 1.6 trở lên) bao gồm mã gốc được viết bằng C/C++, được truy cập thông qua NDK. Tôi tự hỏi cách hiệu quả nhất là truyền một mảng các byte từ Java thông qua NDK đến lớp keo JNI của tôi. Mối quan tâm của tôi là có hay không NDK cho Android sẽ sao chép mảng byte hoặc chỉ cho tôi tham chiếu trực tiếp. Tôi cần truy cập chỉ đọc vào các byte ở cấp độ C++, vì vậy bất kỳ sự sao chép nào đằng sau hậu trường sẽ là một sự lãng phí thời gian từ quan điểm của tôi.Android: Cách hiệu quả nhất để chuyển một số byte chỉ đọc tới C++

Thật dễ dàng để tìm thông tin về điều này trên web, nhưng tôi không chắc chắn thông tin thích hợp nhất là gì. Ví dụ:

Get the pointer of a Java ByteBuffer though JNI

http://www.milk.com/kodebase/dalvik-docs-mirror/docs/jni-tips.html

http://elliotth.blogspot.com/2007/03/optimizing-jni-array-access.html

Vì vậy, không ai biết là tốt nhất (hiệu quả nhất, ít nhất là sao chép) cách để làm điều này trong NDK hiện nay là gì? GetByteArrayRegion? GetByteArrayElements? Thứ gì khác?

Trả lời

5

Theo tài liệu, GetDirectBufferAddress sẽ cung cấp cho bạn tham chiếu mà không cần sao chép mảng.

Tuy nhiên, để gọi hàm này, bạn cần phân bổ direct buffer bằng ByteBuffer.allocateDirect() thay vì một mảng byte đơn giản. Đô thị này có một đối tác là explained here:

Bộ đệm byte trực tiếp có thể được tạo bằng cách gọi phương thức nhà máy allocateDirect của lớp này. Bộ đệm được trả về theo phương pháp này thường có phân bổ cao hơn và chi phí phân bổ cao hơn bộ đệm không trực tiếp. Nội dung của bộ đệm trực tiếp có thể nằm bên ngoài của đống rác thu thập thông thường và do đó tác động của chúng lên dấu chân bộ nhớ của ứng dụng có thể không rõ ràng. Do đó, do đó đề xuất các bộ đệm trực tiếp được phân bổ chủ yếu cho các bộ đệm lớn, tồn tại lâu dài tuân theo các hoạt động I/O cơ bản của hệ thống cơ bản . Nói chung, tốt nhất là chỉ phân bổ bộ đệm trực tiếp khi chúng mang lại mức tăng có thể đo lường được trong chương trình hiệu suất .

+0

Có API tương tự hiệu quả nào để làm ngược lại không? - chuyển 'unsigned char *' từ lớp gốc sang lớp Java dưới dạng 'byte []' hoặc 'byteBuffer'? –

+0

Cả ByteBuffer trực tiếp và byte [] đều có thể được sử dụng để đọc/ghi từ/sang phía gốc. Bạn có thể sử dụng chức năng memcopy của C để đọc/sao chép, một khi bạn đã gọi env-> GetDirectBufferAddress (buffer) hoặc env-> Get ArrayElements (mảng, ...). NHƯNG trực tiếp ByteBuffer nhanh hơn nhiều, không phát bản sao, an toàn hơn, v.v. –