如何从 Android studio 中的 .so 文件调用 function/method
How can I Invoke a function/method from a .so file in Android studio
我正在尝试将 ffmpeg 实现到我的 Android 应用程序中。
我已经有了我需要的预建 .so 文件。
我只是不知道如何调用库中的众多函数之一。
这是我到目前为止所拥有的:
我已将每个 .so 文件放在一个 jniLibs 文件夹下
这是我的 gradle 文件
从那里,我像这样加载库:
static {
Log.e("jni", "starting");
System.loadLibrary("avdevice");
Log.e("jni", "finished");
}
加载成功。到目前为止,一切都很好。
接下来,我查看 .h 文件以找到我可以调用的方法。请注意,我假设此 .h 文件已捆绑到 .so 文件中。这可能就是一切都崩溃的地方。
/**
* Return the LIBAVDEVICE_VERSION_INT constant.
*/
unsigned avdevice_version(void);
因为我现在知道我需要调用的方法名称,所以我将它放在我的代码中:
public native int avdeviceVersion();
当我尝试调用 avdeviceVersion();
时,我收到此错误消息:
java.lang.UnsatisfiedLinkError: No implementation found for int com.my.app.ApplicationContext.avdeviceVersion() (tried Java_com_my_app_ApplicationContext_avdeviceVersion and Java_com_my_app_ApplicationContext_avdeviceVersion__)
现在,我意识到 Java_com_my_app_ApplicationContext_avdeviceVersion
与 .h 文件中的方法名称不匹配。但是,我对如何使其匹配以及下一步该做什么一无所知。如果您知道,请尽可能详尽地解释。假设我什么都不知道:)
更新
我添加了 Android.mk 文件以及 Application.mk,我还添加了一个名为 video.c
.
的 Jni 桥
JNIEXPORT jint JNICALL Java_com_my_app_jni_VideoKit_version(JNIEnv *env, jobject instance, jobjectArray args) {
return (*env)->avdevice_version();}
我的Android.mk是这样的:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice
LOCAL_SRC_FILES := video.c
include $(BUILD_SHARED_LIBRARY)
经过这些更改,结果是一样的。
您应该配置使用 c/c++ classes 的环境。
您需要 CMakeLists.txt 或 Android.mk / Application.mk.
然后,您应该制作一个 class 用于链接 java class 和原生 class.
This link 可以帮到你。
如错误消息所述,
jint Java_{PACKAGE_NAME}_{CLASS_NAME}_{FUNCTION_NAME}(JNIEnv *env, jobject obj)
是必需的。你可以在函数内部调用 avdevice_version()
。
更新
在Android.mk中,先做prebuilt shared library,然后做linking shared library
include $(CLEAR_VARS)
LOCAL_MODULE := static_avdevice # you can change the name
LOCAL_SRC_FILES = avdevice.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include # header file directory
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include # header file directory
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := jniLinker
LOCAL_SRC_FILES := video.c
LOCAL_STATIC_LIBRARIES := static_avdevice
include $(BUILD_SHARED_LIBRARY)
然后,加载库。 System.loadLibrary("jniLinker");
而且,googlesamples 中有很多示例 github。
https://github.com/googlesamples/android-ndk/tree/master/hello-libs
这是使用 3rd 方库的代码示例。 (但它使用 CMake。)
我正在尝试将 ffmpeg 实现到我的 Android 应用程序中。 我已经有了我需要的预建 .so 文件。
我只是不知道如何调用库中的众多函数之一。 这是我到目前为止所拥有的:
我已将每个 .so 文件放在一个 jniLibs 文件夹下
这是我的 gradle 文件
从那里,我像这样加载库:
static {
Log.e("jni", "starting");
System.loadLibrary("avdevice");
Log.e("jni", "finished");
}
加载成功。到目前为止,一切都很好。
接下来,我查看 .h 文件以找到我可以调用的方法。请注意,我假设此 .h 文件已捆绑到 .so 文件中。这可能就是一切都崩溃的地方。
/**
* Return the LIBAVDEVICE_VERSION_INT constant.
*/
unsigned avdevice_version(void);
因为我现在知道我需要调用的方法名称,所以我将它放在我的代码中:
public native int avdeviceVersion();
当我尝试调用 avdeviceVersion();
时,我收到此错误消息:
java.lang.UnsatisfiedLinkError: No implementation found for int com.my.app.ApplicationContext.avdeviceVersion() (tried Java_com_my_app_ApplicationContext_avdeviceVersion and Java_com_my_app_ApplicationContext_avdeviceVersion__)
现在,我意识到 Java_com_my_app_ApplicationContext_avdeviceVersion
与 .h 文件中的方法名称不匹配。但是,我对如何使其匹配以及下一步该做什么一无所知。如果您知道,请尽可能详尽地解释。假设我什么都不知道:)
更新
我添加了 Android.mk 文件以及 Application.mk,我还添加了一个名为 video.c
.
JNIEXPORT jint JNICALL Java_com_my_app_jni_VideoKit_version(JNIEnv *env, jobject instance, jobjectArray args) {
return (*env)->avdevice_version();}
我的Android.mk是这样的:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice
LOCAL_SRC_FILES := video.c
include $(BUILD_SHARED_LIBRARY)
经过这些更改,结果是一样的。
您应该配置使用 c/c++ classes 的环境。 您需要 CMakeLists.txt 或 Android.mk / Application.mk.
然后,您应该制作一个 class 用于链接 java class 和原生 class.
This link 可以帮到你。
如错误消息所述,
jint Java_{PACKAGE_NAME}_{CLASS_NAME}_{FUNCTION_NAME}(JNIEnv *env, jobject obj)
是必需的。你可以在函数内部调用 avdevice_version()
。
更新
在Android.mk中,先做prebuilt shared library,然后做linking shared library
include $(CLEAR_VARS)
LOCAL_MODULE := static_avdevice # you can change the name
LOCAL_SRC_FILES = avdevice.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include # header file directory
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include # header file directory
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := jniLinker
LOCAL_SRC_FILES := video.c
LOCAL_STATIC_LIBRARIES := static_avdevice
include $(BUILD_SHARED_LIBRARY)
然后,加载库。 System.loadLibrary("jniLinker");
而且,googlesamples 中有很多示例 github。 https://github.com/googlesamples/android-ndk/tree/master/hello-libs 这是使用 3rd 方库的代码示例。 (但它使用 CMake。)