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 が呼び出される前後の変数のデバッガー出力を次に示します。構造体 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 ビット Android SDK 19 Android NDK 7rb Eclipse Indigo Java JDK 7.3 Cygwin 1.7.11-1
この問題は、Win 7 や Mac などの他のシステムでも発生します。
ですから、誰かがこれを解決する方法を考えていて、この考えを喜んで私と共有してくれたら、とてもうれしいです。
前もって感謝します!
さようなら、ラウル。
編集:より明確になりました。この値を取得するために使用した gdb デバッガーが誤動作したようです。デバッガーが正しく動作しているかどうかを確認するために、Android ログを介していくつかのテストログを作成しました。
したがって、この質問の解決策は次の質問につながります。ndk-gdb デバッガーが正しく動作しないのはなぜですか?
誰かがこれについてのアイデアを持っているなら、私はとても感謝しています.
そして、私たちが得た助けに感謝したいと思います。