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 が呼び出される前後の変数のデバッガー出力を次に示します。構造体 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 デバッガーが正しく動作しないのはなぜですか?

誰かがこれについてのアイデアを持っているなら、私はとても感謝しています.

そして、私たちが得た助けに感謝したいと思います。

4

0 に答える 0