【问题标题】:Entry point not found, Android .so file未找到入口点,Android .so 文件
【发布时间】:2019-01-29 10:30:00
【问题描述】:

我正在尝试将一些已编译的 C 代码合并到 Android 应用程序中。我已经能够使用 NDK 构建源代码,它生成了一个 .so(7kB)和一个 .a(近 2MB)。

我正在使用 Xamarin,所有说明都说要在项目中包含 .so。我已经完成了,应用程序加载了库。但是,它会引发 EntryPointNotFoundException 异常。这并不让我感到惊讶,因为 .so 除了 RTL 支持函数之外什么都不包含。实际代码在 .a 中。

所以我有两个问题: 1. 如何将 .a 链接到我的 Android 库中? 要么 2. 如何让 NDK 将所有内容打包成一个 .so?

For what it's worth here is the .mk file:

ROOT := $(call my-dir)

# Build libopus
LOCAL_PATH          := ../opus-1.2.1/opus-1.2.1
include $(CLEAR_VARS)
#include the .mk files
include $(LOCAL_PATH)/celt_sources.mk
include $(LOCAL_PATH)/silk_sources.mk
include $(LOCAL_PATH)/opus_sources.mk

LOCAL_MODULE        := opus

#fixed point sources
SILK_SOURCES += $(SILK_SOURCES_FIXED)

#floating point sources - this throws badly!
#SILK_SOURCES += $(SILK_SOURCES_FLOAT)

#ARM build
CELT_SOURCES += $(CELT_SOURCES_ARM)
SILK_SOURCES += $(SILK_SOURCES_ARM)
LOCAL_SRC_FILES     := \
$(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES)

LOCAL_LDLIBS        := -lm -llog


LOCAL_C_INCLUDES    := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/silk \
$(LOCAL_PATH)/silk/float \
$(LOCAL_PATH)/celt

LOCAL_CFLAGS        := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
#LOCAL_CFLAGS        += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DDISABLE_FLOAT_API -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CFLAGS        += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CPPFLAGS      := -DBSD=1
LOCAL_CPPFLAGS      += -ffast-math -O3 -funroll-loops

#include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := opus-share
#LOCAL_SRC_FILES := libopus.a
LOCAL_STATIC_LIBRARIES := opus
include $(BUILD_SHARED_LIBRARY)

谢谢。

【问题讨论】:

  • 从外观上看,您已经将静态库链接到共享库。但是您的作品共享库似乎不包含任何自己的代码。为了能够从 Java 调用任何本机函数,您必须为它们提供 JNI 包装器,即 JNIEXPORT void JNICALL Java_com_example_MyClass_Foo 形式的函数。现在,链接器可能确定共享库中没有引用静态库中的任何代码,因此它不会将任何代码放入共享库中。
  • @Someprogrammerdude 这是一个原生库,可在 Android 应用程序中使用,因此不会有任何 main 函数。
  • @Someprogrammerdude 我不是 OP,但构建共享库在 Android 上做事的正确方法。我的猜测是 OP 根本没有从他的共享库中导出任何函数,然后他试图从他的 C# 代码中调用一个不存在的本机函数。
  • 我想我找到了答案。一旦我有时间深入研究文档。我需要使用 LOCAL_WHOLE_STATIC_LIBRARIES 并且我还需要修复 mk 文件,以便它正确固定点。我会尽快确认它是一个解决方案。

标签: android xamarin android-ndk shared-libraries


【解决方案1】:

我可以确认更改为 LOCAL_WHOLE_STATIC_LIBRARIES 确实是解决方案。原始的 mk 也试图既是定点的又是浮点的。所以最终解决这一切:

# This .mk has to be in a folder called jni. Because :(
ROOT := $(call my-dir)

# Build libopus.a (static library)
LOCAL_PATH          := ../opus-1.2.1/opus-1.2.1
include $(CLEAR_VARS)
#include the .mk files
include $(LOCAL_PATH)/celt_sources.mk
include $(LOCAL_PATH)/silk_sources.mk
include $(LOCAL_PATH)/opus_sources.mk

LOCAL_MODULE        := opus

#fixed point sources
SILK_SOURCES += $(SILK_SOURCES_FIXED)

#floating point sources - this throws badly!
#SILK_SOURCES += $(SILK_SOURCES_FLOAT)

#ARM build
CELT_SOURCES += $(CELT_SOURCES_ARM)
SILK_SOURCES += $(SILK_SOURCES_ARM)
LOCAL_SRC_FILES     := \
$(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES)

LOCAL_LDLIBS        := -lm -llog

LOCAL_C_INCLUDES    := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/silk \
$(LOCAL_PATH)/silk/fixed \
$(LOCAL_PATH)/celt

LOCAL_CFLAGS        := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS        += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DDISABLE_FLOAT_API -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
#LOCAL_CFLAGS        += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno
LOCAL_CPPFLAGS      := -DBSD=1
LOCAL_CPPFLAGS      += -ffast-math -O3 -funroll-loops

include $(BUILD_STATIC_LIBRARY)

# Now create a dynamic library that contains the static library
include $(CLEAR_VARS)
LOCAL_MODULE    := opus-share
#LOCAL_SRC_FILES := opus
LOCAL_WHOLE_STATIC_LIBRARIES := opus
include $(BUILD_SHARED_LIBRARY)

这是使用 Windows NDK 构建的,我必须将该文件(称为 Android.mk)放入名为“JNI”的目录中。可能有一些技巧可以避免涉及环境变量的操作,但我放弃了尝试它。将其与 opus 1.2.1 source code 和平台特定的 mk 文件结合起来,如下所示:

APP_ABI := arm64-v8a
APP_PLATFORM := android-19
APP_STL := c++_static
APP_BUILD_SCRIPT := Android.mk

并且您拥有适用于 Android 的 .so 文件。只需适当更改 ABI 值即可。

【讨论】:

    猜你喜欢
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 2021-05-05
    • 2015-03-10
    • 2012-09-15
    相关资源
    最近更新 更多