我在一个通过 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 调试器不能正常工作?
如果有人对此有想法,我将不胜感激。
我非常感谢我们得到的帮助。