我想在Android的arm程序集中迭代数组数组,但我收到致命信号错误和应用程序崩溃。
我会展示里面的内容。
首先,我使用jni从java访问c代码:
我声明了原生函数:
public native byte[] BitmapToGrayscale(byte[] bitmap);
之后我通过调用此函数来调用我的代码:
private void ConvertImageToGrayscale()
{
if(image == null)
{
GetLenaBack();
info("Nie było obrazu, ustawiono domyślny.");
}
ByteBuffer bb = ByteBuffer.allocate(image.getByteCount());
image.copyPixelsToBuffer(bb);
info("Start");
ByteBuffer result = ByteBuffer.wrap(this.BitmapToGrayscale(bb.array()));
info("Stop");
image.copyPixelsFromBuffer(result);
display.setImageBitmap(image);
}
C中的功能如下:
JNIEXPORT jbyteArray JNICALL Java_pl_marekbar_Main_BitmapToGrayscale
(JNIEnv * env, jobject thisObj, jbyteArray bitmap)
{
jbyte arraySize = (*env)->GetArrayLength(env, bitmap);
jbyte *arrayAddress = (*env)->GetByteArrayElements(env, bitmap, 0);
jbyte cellSize = sizeof((*env)->GetByteArrayElements(env, bitmap, 0));
Grayscale(arrayAddress, arraySize, cellSize);
return bitmap;
}
最后这是我的asm代码:
@ This file is jni/Grayscale.s
.text
.align 2
.global Grayscale
.type Grayscale, %function
Grayscale:
@Convert to grayscale
stmfd sp!, {fp,ip,lr}
@r0 - pointer
@r1 - array length
@r2 - array element size
mov r3, #0 @current element
array_loop:
ldr r4, [r0] @load element to memory
str r4, [r0] @store element in memory
add r0, r0, r4 @move pointer
add r3, r3, #1 @increment index
cmp r3, r1 @compare current index with array length
bne array_loop @when index smaller than array length still iterate
ldmfd sp!, {fp,ip,lr}
bx lr
.size Grayscale, .-Grayscale
我需要了解如何正确使用arm asm中从c代码传递的数组。我不想在C中这样做,因为我正准备应用程序进行图像处理,并且必须快速。
答案 0 :(得分:2)
arraySize
和cellSize
的组合看起来不正确:
jbyte arraySize = (*env)->GetArrayLength(env, bitmap);
jbyte cellSize = sizeof((*env)->GetByteArrayElements(env, bitmap, 0));
jbyte
是int8_t
(即签名的8位类型)。因此arraySize
可能无法保持数组的实际长度,除非您的图像非常小。
您将cellSize
设置为jbyte*
的大小,最有可能是4个字节。这恰好与32位ARGB像素的大小相对应,但它仍然不是确定每个像素大小的正确方法。该信息应作为另一个参数从Java代码传递给C代码。
由于汇编代码重复arraySize
次,它将尝试读取arraySize
个字(即arraySize * 4
个字节)。但是您的数组只包含arraySize
字节。
您在汇编代码中使用了错误的数组指针增量:
ldr r4, [r0] @load element to memory
add r0, r0, r4 @move pointer
您要添加到指针的是您刚从数组中读取的像素数据。就像@ Masta79评论的那样,您可能想要的是将r2
(元素大小)添加到指针。