我正在开发一个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;
}
目标缓冲区不包含任何数据。
我有以下问题:
我很感激有关这个主题的任何建议和想法。
编辑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);
答案 0 :(得分:3)
当您在C中写入DirectByteBuffer时,这不会改变大小(limit)和position dst 缓冲区。你必须自己设置。您可以使用本机代码执行此操作:
jclass cls = (*env)->GetObjectClass(env, dst);
jmethodID limitId = (*env)->GetMethodID(env, cls, "limit", "(I)Ljava/nio/Buffer;");
(*env)->CallObjectMethod(env, dst, limitId, actual_size);
jmethodID positionId = (*env)->GetMethodID(env, cls, "position", "(I)Ljava/nio/Buffer;");
(*env)->CallObjectMethod(env, dst, positionId, 0);
这假设您可以从_decode_buffer()
函数中检索写入 dst 缓冲区的实际字节数。
你不需要翻转()。