1

Android アプリケーションのメモリ ヒープが限られているため、malloc と memcpy を使用して C でビットマップのキャッシュ配列を作成しようとしています。

したがって、Java側には次のものがあります。

private static native Bitmap getJNIBitmap(int id);
private static native void setJNIBitmap(int id, Bitmap bmp);

ビットマップを C に送信するには:

Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
setJNIBitmap(id, bmp);

Cから取得するには:

Bitmap bitmap = getJNIBitmap(id);

Cコードでは、ビットマップのキャッシュを使用したい配列があります:

jobject bitmap_array[100];

CI でビットマップを保存するには:

JNIEXPORT void JNICALL Java_droid_demo_ReadingActivity_setJNIBitmap(JNIEnv* env, jobject obj, jint id, jobject jniBmp) {

  AndroidBitmapInfo info;
  AndroidBitmap_getInfo(env, jniBmp, &info);

  long byteSize = (info.stride * info.height)+16;

  bitmap_array[(int)id] = (jobject *)malloc(byteSize);
  memcpy(bitmap_array[(int)id], jniBmp, byteSize);
  (*env)->NewGlobalRef(env, bitmap_array[(int)id]);
}

C からビットマップを取得するには:

JNIEXPORT jobject JNICALL Java_droid_demo_ReadingActivity_getJNIBitmap(JNIEnv * env, jobject obj, jint id) {

  jobject temp = bitmap_array[(int)id];

  return temp;
}

私は一般的に JNI と C を使用することに慣れていますが、私の頭の中ではこれでうまくいくはずです。そうではなく、私は受け取ります:

10-05 10:35:54.890: W/dalvikvm(12493): JNI WARNING: 0x5d5e0008 is not a valid JNI reference
10-05 10:35:54.890: W/dalvikvm(12493):              in Ldroid/demo/ReadingActivity;.setJNIBitmap:(ILandroid/graphics/Bitmap;)V (NewGlobalRef)
10-05 10:35:54.890: I/dalvikvm(12493): "main" prio=5 tid=1 RUNNABLE
10-05 10:35:54.890: I/dalvikvm(12493):   | group="main" sCount=0 dsCount=0 obj=0x41611568 self=0x416019f8
10-05 10:35:54.890: I/dalvikvm(12493):   | sysTid=12493 nice=0 sched=0/0 cgrp=apps handle=1074710320
10-05 10:35:54.890: I/dalvikvm(12493):   | schedstat=( 7665497000 93442000 221 ) utm=418 stm=348 core=1

bitmap_array[(int)id] をグローバル参照にできない理由についてのアイデアはありますか? そして、この問題を解決する方法さえありますか?

4

2 に答える 2

2

jobject は C ポインターのようにしか見えません。実際には、Java 仮想マシン内の一部の情報への不透明なハンドルです。Java ビットマップ オブジェクトからネイティブ C 配列にピクセル データをコピーすることは可能ですが、特別な API を介してのみ可能です。JNI 関数を使用してネイティブ C コードから Java オブジェクトを作成することもできますが、単純に 2 つの間でキャストすることはできません。

于 2012-10-05T10:29:57.010 に答える
-1

そもそも Java 参照ではないものからグローバル参照を作成しようとしても、意味がありません。NewGlobalRef() の結果に対して何もしていないため、それを呼び出しても意味がありませんが、jniBmp からグローバル参照を作成する場合は、それを NewGlobalRef() に渡し、結果を配列に格納します。また、jobject の内容をコピーしても、そもそもビットマップ データはコピーされません。

于 2012-10-06T01:11:43.077 に答える