2017-09-04 3 views
0

저는 jni 프로그래밍을 처음 접했습니다. Java에서 jni로 float 배열을 전달하고, jni 측에서 배열을 float하기 위해 동적으로 충분한 메모리를 할당하고, jfloatArray에 일부 값을 저장하고, java에 액세스하려고합니다. 내가 jfloatArray를 반환하고 싶지 않아 그냥 전달 된 입력 플로트 배열을 수정하십시오. 나는 아래의 방법을 시도했지만 그것은 내 자바 부동 배열을 수정하지 않습니다. 이것을 달성하는 방법? 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 배열을 포함하는 자바 객체에 대한 JNI에서이 작업을 수행하는 방법을 확실히 모르겠어요.

초기에 pointListInPixels은 Java 객체의 주소 (Java 코드의 float[] pointList)를 나타냅니다.

바로 다음 줄에 (env)->NewFloatArray에 할당합니다. 즉, 은 Java에서 float[] pointList을 가리키지 않지만 새로운 배열을 가리 킵니다. 결과적으로 SetFloatArrayRegion에 전화하면 아무런 효과가 없습니다. Java에서 배열을 수정하지만, 수정하려는 배열은 수정하지 않습니다.

float[] pointList = callJNIFunc(); 

하고 JNI 코드 :

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

방법의 서명이 있어야한다

이 일을 올바른 방법으로 자바 코드를 변환하여 JNI 함수는 jFloatArray를 반환하는 것입니다 필요에 따라 변경되었습니다.

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에서 두 개의 필드가있는 객체를 반환 할 수 있습니다. 또는 두 객체에 두 개의 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; 
} 

객체가 있기 때문에 자바 API (자바 힙 내부)에 의해 생성됩니다. 간단한 메타 로더이 자바 객체의 경우 code snippet