2017-09-04 8 views
0

私はプログラミングの初心者です。 float配列をjavaからjniに渡し、jni側で浮動配列に動的に十分なメモリを割り当て、jfloatArrayにいくつかの値を格納し、javaでアクセスしたいと思います。私はjfloatArrayを返す必要はありません、渡された入力float配列を変更するだけです。私は以下のメソッドを試しましたが、私のjava float配列は変更されていません。これを達成する方法は?JNIプログラミング

Java Code: 

    float[] pointList = null; 
    outputBitmap = callJNIFunc(pointList, inputBitmap); 

JNI Code: 

Bitmap callJNIFunc(JNIEnv *env, jfloatArray pointListInPixels, jobject inputBitmap) { 
    pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2); 
    env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats); 
} 

私は、これはカスタムオブジェクトを渡すことによって達成することができることをpass data between Java and Cから読み取ります。しかし、私はあなたのJNI関数の最初の行で、この

public class CustomObject{ 
    public float[] points; 
    public float[] getPoints() { 
    return points; 
    } 

    public void setPoints(float[] points) { 
    this.points = points; 
    } 

} 

答えて

0

ルックのようなfloat配列を含むJavaオブジェクトのJNIからこれを行う方法をかなりよく分かりません。

最初に、pointListInPixelsはJavaオブジェクトのアドレスを表します(Javaコードのfloat[] pointList)。

次の行では、(env)->NewFloatArrayに割り当てます。つまり、pointListInPixelsはJavaではfloat[] pointListを指していませんが、新しい配列になります。その結果、SetFloatArrayRegionへの電話は無効です。 Javaで配列を変更しますが、変更したい配列は変更されません。

これを行うための正しい方法はにJavaコードを変換し、あなたのJNI関数はjFloatArrayを返すようにすることです:に

float[] pointList = callJNIFunc(); 

とあなたのJNIコード:

メソッドのシグネチャがあるべき
jFloatArray pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2); 
    env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats); 
    return pointListInPixels; 

必要に応じて変更されました。

public class Result{ 
    public final Bitmap bitmap; 
    public final float[] pointListInPixels; 

    public Result(Bitmap bitmap, float[] pointListInPixels){ 
     this.bitmap = bitmap; 
     this.pointListInPixels = pointListInPixels; 
    } 
} 

構造をして、JNIからResultオブジェクトを返す:

+0

しかし、私のjni funcは既に別の戻り値の型を持っています。私はこれを返すことはできません。それが主な問題です。私はそれを参考にして@konsolasを変更したいと思います –

+0

@rsd_unleashed JavaはJNIを含む値渡しです。あなたはこれをすることはできません。 – EJP

+0

JNIから2つのフィールドを持つオブジェクトを返すことができます。または、2つのオブジェクトに対して2つのJNI関数を使用します。 – konsolas

0

あなたはクラス次のように値を返すためコンテナを作成することができますがdeleteする必要はありません。このコードサンプルについて

Result callJNIFunc(JNIEnv *env, jfloatArray pointListInPixels, jobject inputBitmap) { 
    // load class by name 
    jclass cls = env->FindClass("my/package/name/Result"); 
    if (env->ExceptionOccurred()) return NULL; 

    // take constructor by signature 
    jmethodID constructorId = env->GetMethodID(cls, "<init>", "(android/graphics/Bitmap, [[F)V"); 
    if (env->ExceptionOccurred()) return NULL; 

    jobject output_bitmap; // create bitmap and implement logic 

    pointListInPixels = (env)->NewFloatArray(pointListSize.M * 2); 
    env->SetFloatArrayRegion(pointListInPixels, 0, pointListSize.M * 2, pointFloats); 

    // create result object 
    jobject result = env->NewObject(cls, constructorId, output_bitmap, pointListInPixels); 

    return result; 
} 

それらのオブジェクトはJava API(Javaヒープ内部)によって作成されます。 単純なメタローダーをjavaオブジェクトに使用することができますcode snippet