1

我在一个通过 Android NDK 使用本机 C++ 代码的 Android 应用程序中有一些奇怪的结果。当我进行自定义结构的按值调用时,结构成员的值会以某种方式混淆和损坏。这是导致此问题的代码:

ndkfoo.h 的内容:

#ifndef NDKFOO_H_
#define NDKFOO_H_

typedef struct _Point
{
int x;
int y;
} Point;

typedef struct _TdTarget
{
Point tl;       /**< top-left corner */
Point tr;       /**< top-right corner */
Point br;       /**< bottom-right corner */
Point bl;       /**< bottom-left corner */
Point center; /**< estimated center point of the target */
} TdTarget;

#endif /* NDKFOO_H_ */

ndkfoo.c 的内容:

#include "ndkfoo.h"
#include <stdio.h>
#include <string.h>
#include <jni.h>

Point point(int x, int y){
    Point p;
    p.x = x;
    p.y = y;

    return p;
}

void doSomething(TdTarget trgt){
    int i = 0;
    int db1 = sizeof(TdTarget);
    int db2 = db1 + 5;
    if(i == 0)
        printf("");
}    

jstring Java_com_sbkr83_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv*          env,         jobject javaThis) {

TdTarget trgt;
trgt.tl = point(1,2);
trgt.tr = point(3,4);
trgt.br = point(5,6);
trgt.bl = point(7,8);
trgt.center = point(9,11);
int db4 = sizeof(TdTarget);
int db6 = db4 + 5;

doSomething(trgt);

  return "";
}

Android.mk 的内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Here we give our module name and source file(s)
LOCAL_MODULE    := ndkfoo
LOCAL_SRC_FILES := ndkfoo.c

include $(BUILD_SHARED_LIBRARY)

Application.mk 的内容:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a 

以及 NdkFooActivity 的内容:

package com.sbkr83.ndkfoo;

import android.app.Activity;
import android.os.Bundle;

public class NdkFooActivity extends Activity {

  // load the library - name matches jni/Android.mk
  static {
    System.loadLibrary("ndkfoo");
  }

  // declare the native code function - must match ndkfoo.c
  private native String invokeNativeFunction();

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // this is where we call the native code
        invokeNativeFunction();
    }
}

这是调用 doSomething 前后变量的调试器输出。查看 struct trgt 的值:

打电话前:

env 0x0000aeb8  
javaThis    0x2afca558  
trgt    {...}   
    tl  {...}   
        x   1   
        y   2   
    tr  {...}   
        x   3   
        y   4   
    br  {...}   
        x   5   
        y   6   
    bl  {...}   
        x   7   
        y   8   
    center  {...}   
        x   9   
        y   11  

在调用 doSomething 之后:

trgt    {...}   
    tl  {...}   
        x   5   
        y   6   
    tr  {...}   
        x   7   
        y   8   
    br  {...}   
        x   9   
        y   11  
    bl  {...}   
        x   9   
        y   11  
    center  {...}   
i       2   
db1     1   
db2 2123359160

如您所见,这些值被混淆和损坏了。非常有趣的是,局部变量的值也不正确。在我看来,带有局部变量和参数的堆栈框架完全搞砸了。但我不知道为什么。相同的代码在带有 MS Visual Studio 的 Windows 系统上运行没有任何错误。

我的开发系统:Windows XP SP 3 32-bit Android SDK 19 Android NDK 7rb Eclipse Indigo Java JDK 7.3 Cygwin 1.7.11-1

该问题也出现在 Win 7 或 Mac 等其他系统上。

所以,如果有人知道如何解决这个问题并愿意与我分享这个想法,我会很高兴。

提前致谢!

再见,拉乌尔。

编辑:现在变得更清楚了。看来,我们用来检索这些值的 gdb 调试器刚刚出现故障。我们通过 Android 日志制作了一些测试日志,以了解调试器是否正常工作。

所以,这个问题的解决方案引出了下一个问题:为什么 ndk-gdb 调试器不能正常工作?

如果有人对此有想法,我将不胜感激。

我非常感谢我们得到的帮助。

4

0 回答 0