JNI接口的实现中,有一段代码,功能是从一副图片中截取中间一部分,具体实现是这样的:
unsigned char *fun(unsigned char *data, int width, int height, int leftTopX, int leftTopY, int nWidth, int nheight)
//data, 图片内存首地址,width, height, 图片宽和高;
//leftTopX, leftTopY,截取区域左上角的点坐标
//nWidth, nHeight, 截取区域的宽和高
{
        unsigned char *temp, *tempN; 
        unsigned char *pxl;
        int size = nWidth * nHeight;
pxl = NULL;
if ((pxl = (unsigned char *)malloc(size * sizeof(unsigned char))) == NULL)
{
return NULL;
}
memset(readImg->pxl, 0x00, sizeof(size * sizeof(unsigned char)));
temp = data + width  * leftTopY + leftTopX;
tempN = pxl;
for (i = 0; i < nHeight; i++)
{
__android_log_print(ANDROID_LOG_INFO, "[hello-jni.c]", "i is %d", i);
memcpy(tempN, temp, nWidth);
                __android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_0");
temp += width;
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_1");
tempN += nWidth;
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_2");
}        return pxl;
}上面是这部分完整的代码,这个应用在大部分android手机上都没有问题,但在阿里云手机上就会出错。出现的问题是这样的,
假设nHeight是200,那要循环200次,可是从log上看,每次出错都是循环没有运行完,而且是memcpy这一句出错。请大侠帮忙看看,问题怎么解决?

解决方案 »

  1.   

    我把运行过程中所有的参数都打印出来了,data,pxl,temp,tempN四个指针用十六进制的形式打印。
    下面是log里的内容:01-02 04:36:42.870: W/System.err(3364): width:800
    01-02 04:36:42.870: I/[hello-jni.c](3364): data is 407591e8
    01-02 04:36:42.870: I/[hello-jni.c](3364): size is 67200
    01-02 04:36:42.870: I/[hello-jni.c](3364): pxl is 40040008
    01-02 04:36:42.870: I/[hello-jni.c](3364): width is 800,
    01-02 04:36:42.870: I/[hello-jni.c](3364): height is 448,
    01-02 04:36:42.870: I/[hello-jni.c](3364): nWidth is 200,
    01-02 04:36:42.870: I/[hello-jni.c](3364): nHeight is 336,
    01-02 04:36:42.870: I/[hello-jni.c](3364): leftTopX is 300,
    01-02 04:36:42.870: I/[hello-jni.c](3364): leftTopY is 56,
    01-02 04:36:42.870: I/[hello-jni.c](3364): i is 0
    01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 40764214, tempN is 40040008
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
    01-02 04:36:42.870: I/[hello-jni.c](3364): i is 1
    01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 40764534, tempN is 400400d0
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
    01-02 04:36:42.870: I/[hello-jni.c](3364): i is 2
    01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 40764854, tempN is 40040198
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
    ……
    ……
    ……
    01-02 04:36:42.870: I/[hello-jni.c](3364): i is 213
    01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 4078dbb4, tempN is 4004a670
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
    01-02 04:36:42.870: I/[hello-jni.c](3364): i is 214
    01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 4078ded4, tempN is 4004a738
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
    01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
    01-02 04:36:42.870: I/[hello-jni.c](3364): i is 215
    01-02 04:36:42.900: V/NvOmxCamera(19858): First preview frame displayed
    01-02 04:36:42.900: V/NvOmxCamera(19858): ReleaseWakeLock
    01-02 04:36:42.900: V/NvOmxCamera(19858): NvOmxCamera::NvOmxCameraGraphEventHandler --输入data地址为0x407591e8;pxl初始化为0x40040008;
    第一次循环:
    temp是0x40764214,  0x40764214 == 0x407591e8(data) + 800(width) * 56(leftTopY ) + 300(leftTopX),
    tempN是0x40040008,0x40040008 == 0x40040008;
    第二次循环:
    temp:  0x40764534 - 0x40764214 == 800(width);
    tempN: 0x400400d0 - 0x40040008 == 200(nWidth);从这些参数里都看不出问题。循环到215次时就出错了,memcpy()那一句后面的log都没有打印出来。
      

  2.   

    我又试了一下,把这一段先给屏了,测后面的代码,发现还有这些问题:
    1,memcpy()函数,参数size值大的情况下,会出错,其后的log打印不出来。
    比如copy一幅图片的内存,一次copy整幅图的话,就出错了,
    分成一行一行copy的话,就可以运行下去。
    2,接问题1,一幅图一行一行copy,需要循环height次,
    这里我的height是448,一般循环到200多次的时候会挂掉。
    这些都 是从log上看出来的。
      

  3.   

    01-02 04:36:42.870: W/System.err(3364): width:800
    01-02 04:36:42.870: I/[hello-jni.c](3364): width is 800,
    01-02 04:36:42.870: I/[hello-jni.c](3364): height is 448,
    为什么你的width > height ? 本身就是这样的值?
    再把其他正常的手机中的值打印出来对比一下呢
      

  4.   

    memset(readImg->pxl, 0x00, sizeof(size * sizeof(unsigned char)));
    //readImg->pxl=px1要吗?
     tempN = pxl;
     for (i = 0; i < nHeight; i++)
     //i<nHeight-leftTopY吧
      

  5.   

    》》循环到215次时就出错了,memcpy()那一句后面的log都没有打印出来。
    有可能是log太多的缘故,未必是问题
      

  6.   

    多谢谢大家的提示,我觉得根源还是在空间(data 和 pxl)是否足够这一块.
    我现在发现这个问题,我的接口是这样的:
    unsigned char *fun(unsigned char *data, int width, int height, int leftTopX, int leftTopY, int nWidth, int nheight);
    按正常思路,data所指向空间的大小应该和width、height匹配。
    我最初想的是空间大小应该等于width*height。
    但实际中发现不是这样的。我这试了三款手机,A和B上运行正常,C上运行错误,就是前面提到的那些问题。
    A机的三个值:空间大小614800,width854, height480;
    B机的三个值:空间大小514800,width720, height480;
    C机的三个值:空间大小115200,width800, height448;
    这些值都是Java调用端得到的。分析这三组值,发现
    614800 > 854 * 480; 614800 / 2 == 854 * 480;
    514800 > 720 * 480; 514800 / 2 == 720 * 480;
    115200 < 800 * 448;现在想不通的是,为什么空间大小不等于width*height,这些可都是8位灰度图啊。另外大家在android上开发相机图片应用时,获取的图片数据有没有发现这一问题呢?
      

  7.   

    朋友,是java与c的char的定义不一样的缘故吧,一个是unicode,一个是ansi。
      

  8.   

    应该不是这个原因,我对java不熟,我和手机端的开发人员联调,
    他们帮忙取到了data空间的大小,发现这个大小比width*height小,这个是问题的原因,
    当时取width和height是手机说明的分辨率大小,后来用另一种方法取到了一组新的width、height,这样两部分就吻合了,再传进来就OK,
    至于用什么办法取到的width和height,我也不知道了,