java将数据从JNI函数返回到Android应用程序代码
我正在开发一个Android应用程序,我正在使用一个本机C库。此库用于文件解压缩
本机方法的定义如下:
public static native Long decompress(ByteBuffer src, ByteBuffer dst);
我使用此功能的应用程序代码如下:
try {
File inFile = new File(Environment.getExternalStorageDirectory().getPath() +"/1"); // source file
ByteBuffer buf = ByteBuffer.allocateDirect((int)inFile.length());
ByteBuffer buf_out = ByteBuffer.allocateDirect((int)inFile.length()*20);
InputStream is = new FileInputStream(inFile);
int b;
while ((b=is.read())!=-1) {
buf.put((byte)b);
}
Log.d("nims","source buffer zie"+buf.position());
File file = new File(Environment.getExternalStorageDirectory().getPath() +"/2");
// append or overwrite the file
boolean append = false;
FileChannel channel = new FileOutputStream(file, append).getChannel();
Long t = decompress(buf,buf_out); // t is some XYZ number
Log.d("nims","dest buffer zie"+buf_out.position()); // buf_out.position() returns 0
buf_out.flip();
// Writes a sequence of bytes to this channel from the given buffer.
channel.write(buf_out);
// close the channel
channel.close();
}
catch (IOException e) {
System.out.println("I/O Error: " + e.getMessage());
}
JNI代码:
JNIEXPORT jlong JNICALL
Java_com_company_appName_MainActivity_decompress(JNIEnv* env, jclass cls, jobject src, jobject dst) {
uint8_t* src_buffer = (*env)->GetDirectBufferAddress(env,src);
const size_t src_size = (*env)->GetDirectBufferCapacity(env, src);
uint8_t* dst_buffer = (*env)->GetDirectBufferAddress(env,dst);
size_t dst_size = (*env)->GetDirectBufferCapacity(env, dst);
jlong test = _decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
return test;
}
目标缓冲区不包含任何数据
我有以下问题:
- 如何将目标bytebuffer从JNI代码读回应用程序代码李>
- 如何将目标bytebuffer数据写入文件李>
如果您对这个话题有任何建议和想法,我将不胜感激
编辑1:
size_t test = lzfse_decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
ALOG("Size of test %d.",test); // output is 319488
ALOG("Size of test after casting %ld.",(jlong)test); // output is -125648933
//New code from stack overflow
jclass cls2 = (*env)->GetObjectClass(env, dst);
jmethodID limitId = (*env)->GetMethodID(env, cls2, "limit", "(I)Ljava/nio/Buffer;");
(*env)->CallObjectMethod(env, dst, limitId,(jlong) test);
jmethodID positionId = (*env)->GetMethodID(env, cls2, "position", "(I)Ljava/nio/Buffer;");
(*env)->CallObjectMethod(env, dst, positionId, 0);
编辑2:
size_t test = lzfse_decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
ALOG("Size of test %d.",test); // output is 319488
ALOG("Size of test after casting %d.",(jint)test); // output is 319488
//New code from stack overflow
jclass cls2 = (*env)->GetObjectClass(env, dst);
jmethodID limitId = (*env)->GetMethodID(env, cls2, "limit", "(I)Ljava/nio/Buffer;");
(*env)->CallObjectMethod(env, dst, limitId,(jint) test);
jmethodID positionId = (*env)->GetMethodID(env, cls2, "position", "(I)Ljava/nio/Buffer;");
(*env)->CallObjectMethod(env, dst, positionId, 0);
# 1 楼答案
在C中写入DirectByteBuffer时,这不会更改大小(limit)和position dst缓冲区的。你必须自己设置这些。您可以在本机代码中执行此操作:
这假设您可以从
_decode_buffer()
函数检索写入dst缓冲区的实际字节数而且您不需要flip()