0

私はandroid-ndkを使用して作業しようとしています。このような問題に直面しました:jni部分で使用するためにバッファを割り当ててから解放する必要があります。私はここでそのような実現を見つけました: jni部分の関数:

    jobject Java_com_domain_applicationname_FFMpegWrapper_allocNative(JNIEnv* env, jobject thiz, jlong size)
{
void* buffer = malloc(size);
jobject directBuffer = (*env)->NewDirectByteBuffer(env, buffer, size);
jobject globalRef = (*env)->NewGlobalRef(env, directBuffer);
return globalRef;
}
void Java_com_domain_applicationname_FFMpegWrapper_freeNative(JNIEnv* env, jobject thiz, jobject globalRef)
{
void *buffer = (*env)->GetDirectBufferAddress(env, globalRef);
free(buffer);
(*env)->DeleteGlobalRef(env, globalRef);
}

Java の部分では、次のようにします。

   public class FFMpegWrapper {
.........
/** allocate buffer*/
public static native ByteBuffer allocNative(long bufferSize);

/** free buffer*/
public static native void freeNative(ByteBuffer buffer);
}

MainActivity での onCreate:

 long bufferSize = 1024;
    ByteBuffer my_buffer = FFMpegWrapper.allocNative(bufferSize);
    FFMpegWrapper.logFileInfo("/storage/sdcard0/movies/126_3_17.avi");//this function I won't describe it business doesn't treat but it works it is visible from logs below
    //to here everything works well
    FFMpegWrapper.freeNative(my_buffer);//and here we receive a departure from the program and even the window of an exception isn't shown simply is closed activity.

LogCat:

01-14 17:53:06.924: I/com.domain.tag(22249): initialize_passed
01-14 17:53:06.964: I/com.domain.tag(22249): openened
01-14 17:53:06.964: I/ttag(22249): 3270391527096277528
01-14 17:53:06.984: I/com.domain.tag(22249): File was opened
01-14 17:53:06.984: I/com.domain.tag(22249): File '/storage/sdcard0/Movies/126_3_17.avi', Codec avi
01-14 17:53:06.984: W/dalvikvm(22249): JNI WARNING: DeleteGlobalRef on non-global 0x4780001d (type=1)
01-14 17:53:06.984: I/dalvikvm(22249): "main" prio=5 tid=1 NATIVE
01-14 17:53:06.984: I/dalvikvm(22249): | group="main" sCount=0 dsCount=0 obj=0x41065568 self=0x40ebe9a0
01-14 17:53:06.984: I/dalvikvm(22249): | sysTid=22249 nice=0 sched=0/0 cgrp=apps handle=1074450224
01-14 17:53:06.984: I/dalvikvm(22249): | schedstat=( 74908625 168640538 138 ) utm=4 stm=2 core=0
01-14 17:53:06.999: I/dalvikvm(22249): #00 pc 00001260 /system/lib/libcorkscrew.so (unwind_backtrace_thread+27)
01-14 17:53:06.999: I/dalvikvm(22249): #01 pc 0005f904 /system/lib/libdvm.so (dvmDumpNativeStack(DebugOutputTarget const*, int)+35)
01-14 17:53:06.999: I/dalvikvm(22249): #02 pc 000537ac /system/lib/libdvm.so (dvmDumpThreadEx(DebugOutputTarget const*, Thread*, bool)+303)
01-14 17:53:06.999: I/dalvikvm(22249): #03 pc 00053846 /system/lib/libdvm.so (dvmDumpThread(Thread*, bool)+25)
01-14 17:53:06.999: I/dalvikvm(22249): #04 pc 00038e02 /system/lib/libdvm.so
01-14 17:53:06.999: I/dalvikvm(22249): #05 pc 000414da /system/lib/libdvm.so
01-14 17:53:06.999: I/dalvikvm(22249): #06 pc 0002f728 /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so (Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_freeNative+25)
01-14 17:53:06.999: I/dalvikvm(22249): #07 pc 0001de70 /system/lib/libdvm.so (dvmPlatformInvoke+112)
01-14 17:53:06.999: I/dalvikvm(22249): #08 pc 0004d0c2 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+393)
01-14 17:53:06.999: I/dalvikvm(22249): #09 pc 0004f1dc /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+171)
01-14 17:53:06.999: I/dalvikvm(22249): #10 pc 000272a0 /system/lib/libdvm.so
01-14 17:53:06.999: I/dalvikvm(22249): #11 pc 0002bba8 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
01-14 17:53:06.999: I/dalvikvm(22249): #12 pc 0005faf6 /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+373)
01-14 17:53:06.999: I/dalvikvm(22249): #13 pc 0006709c /system/lib/libdvm.so
01-14 17:53:06.999: I/dalvikvm(22249): #14 pc 000272a0 /system/lib/libdvm.so
01-14 17:53:06.999: I/dalvikvm(22249): #15 pc 0002bba8 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
01-14 17:53:06.999: I/dalvikvm(22249): #16 pc 0005f830 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+271)
01-14 17:53:06.999: I/dalvikvm(22249): #17 pc 000496b2 /system/lib/libdvm.so
01-14 17:53:06.999: I/dalvikvm(22249): #18 pc 0004c44e /system/lib/libandroid_runtime.so
01-14 17:53:06.999: I/dalvikvm(22249): #19 pc 0004d556 /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+389)
01-14 17:53:07.004: I/dalvikvm(22249): #20 pc 00000dce /system/bin/app_process
01-14 17:53:07.004: I/dalvikvm(22249): #21 pc 00017120 /system/lib/libc.so (__libc_init+35)
01-14 17:53:07.004: I/dalvikvm(22249): at ru.dzakhov.ffmpeg.test.FFMpegWrapper.freeNative(Native Method)
01-14 17:53:07.004: I/dalvikvm(22249): at ru.dzakhov.ffmpeg.test.MainActivity.onCreate(MainActivity.java:39)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.Activity.performCreate(Activity.java:5184)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1083)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.ActivityThread.access$600(ActivityThread.java:140)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
01-14 17:53:07.004: I/dalvikvm(22249): at android.os.Handler.dispatchMessage(Handler.java:99)
01-14 17:53:07.004: I/dalvikvm(22249): at android.os.Looper.loop(Looper.java:137)
01-14 17:53:07.004: I/dalvikvm(22249): at android.app.ActivityThread.main(ActivityThread.java:4898)
01-14 17:53:07.004: I/dalvikvm(22249): at java.lang.reflect.Method.invokeNative(Native Method)
01-14 17:53:07.004: I/dalvikvm(22249): at java.lang.reflect.Method.invoke(Method.java:511)
01-14 17:53:07.004: I/dalvikvm(22249): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
01-14 17:53:07.004: I/dalvikvm(22249): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
01-14 17:53:07.004: I/dalvikvm(22249): at dalvik.system.NativeStart.main(Native Method)
01-14 17:53:07.004: E/dalvikvm(22249): VM aborting
01-14 17:53:07.004: A/libc(22249): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 22249 (hov.ffmpeg.test)

私は何を間違っていますか?

4

1 に答える 1

0

JNI について: http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp16785

  1. Objects are passed to native methods as local references. これは、グローバル ref をネイティブ側に格納する必要があることを意味します。グローバル ref を Java に戻すと、ローカル オブジェクトとしてラップされます。したがって、後で解放しようとすると、このローカル オブジェクトがコードに渡されます。
  2. ローカルからグローバル ref を作成する場合 - 不要になった場合はローカル ref を解放します。

したがって、割り当てられたグローバル オブジェクト (または割り当てられたバッファー) のある種のマップを維持し、NewDirectByteBuffer によって返される jobject へのローカル参照を返すことができます。

于 2013-01-15T17:35:39.850 に答える