概要
- ByteBuffer.allocateDirect(someBufferSize) で buffer と呼ばれる Java で ByteBuffer を作成します。
- バッファをデータで埋める
- バッファを C++ に jobject として渡す - jbuffer
- env->GetDirectBufferAddress(jbuffer) でバッファダイレクトポインタを取得
- C++ 側でバッファ データを操作します。GC がバッファーをクリーンアップしないようにするにはどうすればよいでしょうか?
- 作業は完了しました - 今は jbuffer は必要ありません。
- jbuffer を解放しますか? free(jbuffer) - 無効なアドレス エラーが発生します
長い部分
次のコードを使用して Java AssetManager で PNG ファイルを読み込み、Open GL ES 2.0 テクスチャの作成に使用します。
Java側のPNGクラス
import java.nio.ByteBuffer;
import android.graphics.Bitmap;
public class PNG
{
private static final int BYTES_PER_PIXEL_PNG = 4;
private static final String LOG_TAG = "[PNG]";
public int width;
public int height;
public ByteBuffer pixels;
public PNG(Bitmap bitmap)
{
this.width = bitmap.getWidth();
this.height = bitmap.getHeight();
this.pixels = ByteBuffer.allocateDirect(this.width * this.height * BYTES_PER_PIXEL_PNG);
bitmap.copyPixelsToBuffer(this.pixels);
}
}
public static PNG loadPNG(String path)
{
InputStream is = null;
try
{
is = ASSETS_MANAGER.open(path);//get png file stream with AssetsManager instance
}
catch (IOException e)
{
Log.e(LOG_TAG, "Can't load png - " + path, e);
}
return new PNG(BitmapFactory.decodeStream(is));
}
C++ 側の PNG
typedef struct png
{
int width;
int height;
char* pixels;
} png;
png* load_png(const char* path)
{
png* res = (res*) malloc(sizeof(png);
...
jobject _png = env->CallStaticObjectMethod(get_java_lib_class(), get_method_id(JAVA_LIB_LOAD_PNG, JAVA_LIB_LOAD_PNG_SIGN), _path);//Calling loadPng() from Java, get PNG jobject
jobject _pixels = env->GetObjectField(_png, PNG_FIELDS->PNG_PIXELS_ID);//Getting pixels field from Java PNG jobject
res->pixels = (char*) env->GetDirectBufferAddress(_pixels);//Get direct pointer to our pixel data
//Cleanup
...
env->DeleteLocalRef(_png);
env->DeleteLocalRef(_pixels);
return res;
}
次に、pngを使用してテクスチャを作成します
void test_create_tex(const char* path)
{
...
png* source = load_png(path);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, source->width, source->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, source->pixels);
//We don't need source pixel data any more
//free(source->pixels);//INVALID HEAP ADDRESS (deadbaad)
free(source);
}
では、直接ポインタを使用して C++ 側で使用した後、バイト バッファを解放するにはどうすればよいでしょうか。それは直接割り当てられ(mallocのように-ネイティブ側で)、解放する必要があります。そうしないと、OutOfMemoryエラーが発生します。