在 Android 上尝试 impl C 库,但应用程序崩溃
Try impl C library on Android but app crashes
我想将 C 库添加到我的项目中。 lzfse 用于通过苹果算法解码 img。
我已将 c 文件添加到项目中
添加了 CmakeLines 文件:
externalNativeBuild {
cmake {
path "src/main/lzfse/CMakeLists.txt"
version "3.10.2"
}
}
我已经为 decode
编写了 JNI:
JNIEXPORT jint JNICALL
Java_com_android_Decompressor_decode(
JNIEnv* env, jclass cls, jobject src, jobject dst
) {
uint8_t* src_buffer = (*env)->GetDirectBufferAddress(env,src);
const size_t src_size = (const size_t) (*env)->GetDirectBufferCapacity(env, src);
uint8_t* dst_buffer = (*env)->GetDirectBufferAddress(env,dst);
size_t dst_size = (size_t) (*env)->GetDirectBufferCapacity(env, dst);
jlong test = lzfse_decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
return (jint) test;
}
然后我调用 kt decode fun:
val buf = ByteBuffer.wrap(byteArray)
val buf_out = ByteBuffer.allocateDirect(byteArray.size *20)
val size= decode(dstArray = buf_out, srcArray = buf)
但是
我的应用程序崩溃了
2020-02-25 20:12:25.717 28603-28603/com.android A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 28603 (), pid 28603 ()
我哪里输了?
包装 ByteArray
does not result in a direct buffer(至少在 Android 上)。
您将需要调用 GetByteArrayElements
来获取(可能复制的)指针。
我已经修复了崩溃问题!一段时间后,我决定发布工作代码。
因此,从项目调用本机 c++:
private val dstArray: ByteBuffer = ByteBuffer.allocateDirect(DESTINATION_BUFFER_CAPACITY)
private val srcArray: ByteBuffer = ByteBuffer.allocateDirect(SRC_BUFFER_CAPACITY)
decode(srcArray.put(byteArray), dstArray)
此处代替:
val buf = ByteBuffer.wrap(byteArray)
val size= decode(dstArray = buf_out, srcArray = buf)
我通过 ByteBuffer.allocateDirect
分配一个直接缓冲区,并将源数组放在缓冲区 srcArray.put(byteArray)
中。
因为 @Botje said in his :
Wrapping a ByteArray does not result in a direct buffer (at least on
Android).
我的 JNI:
JNIEXPORT JNICALL
Java_com_android_Decompressor_decode(
JNIEnv *env, jclass cls, jobject src, jobject dst
) {
uint8_t *src_buffer = (*env)->GetDirectBufferAddress(env, src);
const size_t src_size = (const size_t) (*env)->GetDirectBufferCapacity(env, src);
uint8_t *dst_buffer = (*env)->GetDirectBufferAddress(env, dst);
size_t dst_size = (size_t) (*env)->GetDirectBufferCapacity(env, dst);
lzfse_decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
}
所以我几乎没改过JNI。
但是在我的第一个代码示例中,我发现所有的工作直到行:
//...
return (jint) test;
导致崩溃的线路。
在我的例子中,我不需要 return 值,所以我重写了没有 return 任何值的 JNI 函数,但我认为可以找到我失败的地方 return 值。
谢谢那些试图提供帮助的人,我希望我的 post 也能对某人有所帮助。
我想将 C 库添加到我的项目中。 lzfse 用于通过苹果算法解码 img。
我已将 c 文件添加到项目中
添加了 CmakeLines 文件:
externalNativeBuild {
cmake {
path "src/main/lzfse/CMakeLists.txt"
version "3.10.2"
}
}
我已经为 decode
编写了 JNI:
JNIEXPORT jint JNICALL
Java_com_android_Decompressor_decode(
JNIEnv* env, jclass cls, jobject src, jobject dst
) {
uint8_t* src_buffer = (*env)->GetDirectBufferAddress(env,src);
const size_t src_size = (const size_t) (*env)->GetDirectBufferCapacity(env, src);
uint8_t* dst_buffer = (*env)->GetDirectBufferAddress(env,dst);
size_t dst_size = (size_t) (*env)->GetDirectBufferCapacity(env, dst);
jlong test = lzfse_decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
return (jint) test;
}
然后我调用 kt decode fun:
val buf = ByteBuffer.wrap(byteArray)
val buf_out = ByteBuffer.allocateDirect(byteArray.size *20)
val size= decode(dstArray = buf_out, srcArray = buf)
但是 我的应用程序崩溃了
2020-02-25 20:12:25.717 28603-28603/com.android A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 28603 (), pid 28603 ()
我哪里输了?
包装 ByteArray
does not result in a direct buffer(至少在 Android 上)。
您将需要调用 GetByteArrayElements
来获取(可能复制的)指针。
我已经修复了崩溃问题!一段时间后,我决定发布工作代码。 因此,从项目调用本机 c++:
private val dstArray: ByteBuffer = ByteBuffer.allocateDirect(DESTINATION_BUFFER_CAPACITY)
private val srcArray: ByteBuffer = ByteBuffer.allocateDirect(SRC_BUFFER_CAPACITY)
decode(srcArray.put(byteArray), dstArray)
此处代替:
val buf = ByteBuffer.wrap(byteArray)
val size= decode(dstArray = buf_out, srcArray = buf)
我通过 ByteBuffer.allocateDirect
分配一个直接缓冲区,并将源数组放在缓冲区 srcArray.put(byteArray)
中。
因为 @Botje said in his
Wrapping a ByteArray does not result in a direct buffer (at least on Android).
我的 JNI:
JNIEXPORT JNICALL
Java_com_android_Decompressor_decode(
JNIEnv *env, jclass cls, jobject src, jobject dst
) {
uint8_t *src_buffer = (*env)->GetDirectBufferAddress(env, src);
const size_t src_size = (const size_t) (*env)->GetDirectBufferCapacity(env, src);
uint8_t *dst_buffer = (*env)->GetDirectBufferAddress(env, dst);
size_t dst_size = (size_t) (*env)->GetDirectBufferCapacity(env, dst);
lzfse_decode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL);
}
所以我几乎没改过JNI。 但是在我的第一个代码示例中,我发现所有的工作直到行:
//...
return (jint) test;
导致崩溃的线路。
在我的例子中,我不需要 return 值,所以我重写了没有 return 任何值的 JNI 函数,但我认为可以找到我失败的地方 return 值。 谢谢那些试图提供帮助的人,我希望我的 post 也能对某人有所帮助。