【问题标题】:Link .so library in android studio project在 android studio 项目中链接 .so 库
【发布时间】:2018-07-14 15:45:29
【问题描述】:

正如标题所示,我正在尝试将原生 .so 链接到 android studio 项目。我浏览了 android 开发者网站中的文档和更多文章,但未能成功将 .so 文件与项目连接起来。

每当我尝试运行代码时,我都会收到以下错误

CMake 错误:此项目中使用了以下变量,但是 它们被设置为 NOTFOUND。请设置它们或确保它们已设置 并在 CMake 文件中正确测试:testlib

这是我的 CMake 文件

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

add_library(testlib SHARED IMPORTED)

set_property(TARGET testlib PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/libremotedesktop_client.so")

#find_path(testlib E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/RemoteDesktop.h)
find_library(testlib E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/libremotedesktop_client.so)

#add_library(remote SHARED IMPORTED)

#set_target_properties(remote PROPERTIES IMPORTED_LOCATION libs/${ANDROID_ABI}/libremotedesktop_client.so )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib}

                       ${testlib})

target_include_directories()

我有四个 .so 文件,每个文件用于 arm64、armeabi、armeabi-v7a、x86。我已经在路径中对 armeabi-v7a 库进行了编码,当我这样做时,android studio 会抛出上述错误。我的实际目标是根据手机中的芯片动态加载库。我很确定我当前的代码没有实现这一点。

这是我的疑问

  1. 如何解决我遇到的错误?我试过同时给出相对路径和绝对路径,但无济于事,我得到了同样的错误。

  2. 如何将.so 和.h 文件添加到本机android studio 项目中?这会根据运行代码的芯片而有所不同吗?

  3. 当我直接将.h 文件添加到本机文件夹时,我可以在我的 C 代码中引用该标头中的类和函数,但我无法运行该代码。我在.h 文件中有一个getInstance() 方法。每当我打电话给 getInstance() 函数它说undefined refernce to getInstance()。我从中了解到的是“.h”文件已正确链接,但.h 文件中实际存在的.so 文件的功能定义未链接。我相信只要回答了问题 1 和 2,这个问题就会得到解决。

  4. 是否所有原生安卓项目都必须有一个.mk 文件?我没有在我的项目中添加一个,并认为这可能是我遇到错误的原因之一。

【问题讨论】:

  • “这是我的疑问” - 所以问题应该是每个帖子一个问题,而不是多个问题。
  • @JesperJuhl 。您可能是对的,如果我的每个查询都有不同的答案,则该规则适用。我相信我在某些方面犯了一个菜鸟错误,这将清除我所有的 4 个疑问,这就是为什么我决定将它们全部放在一个问题中。如果这些查询的答案似乎不同,我稍后会将它们分成不同的问题。干杯:)
  • 看看这个示例:github.com/googlesamples/android-ndk/tree/master/hello-libs "这个示例使用带有外部库支持的 Android Studio CMake 插件。它演示了如何:(*) 包含一个预构建的静态库(gmath) 在您的应用中;(*) 在您的应用中包含一个预构建的共享库 (gperf)"

标签: android c++ android-ndk shared-libraries


【解决方案1】:

在您的情况下,您不需要 find_library。对于log,库由NDK为你解析;对于 libremotedesktop_client.so,您知道确切的路径。

以下是适合您的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

add_library(remote SHARED IMPORTED)

set_property(TARGET remote PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/${ANDROID_ABI}/libremotedesktop_client.so")

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       log

                       remote)

请注意,在 CMake 脚本中使用完整路径 (E:/project...) 不是最佳做法;您可能可以相对于 CMakeLists.txt 的路径(即${CMAKE_CURRENT_SOURCE_DIR})以某种方式表达该库的路径。

【讨论】:

  • 该死的。大多数与 CMake 相关的答案都很长。这似乎是最短的,解决了我的问题。我的情况是:CMake 版本 3.10.2,所以我没有 target_link_directories,如果您的版本 > 3.10,这似乎是一个解决方案。最初我想链接一个我在 Android Studio 中自己的模块中构建的库。 add_library 和 set_property 的组合起到了作用。谢谢
  • @hundolin 他们现在正在通过 Prefab 处理 AS 中的模块间原生依赖项。见github.com/android/ndk/issues/1559
【解决方案2】:

1-2)。首先,在 CMakeLists.txt 的开头添加set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)(就在cmake_minimum_required(...) 之后),以允许库的另一个搜索路径。在此之后,您可以使用标准 find_library 找到 lib:

find_library(FOO_LIBRARY
         foo # Lib's full name in this case - libfoo.so
         PATHS path/to/lib/)
if (NOT FOO_LIBRARY)
    message(FATAL_ERROR "Foo lib not found!")
endif()

您可以使用变量ANDROID_ABI 来获取特定的库版本,如果目录以这种方式组织的库:

- path/to/lib
       - armeabi-v7a
           - libfoo.so
       - arm64-v8a
           - libfoo.so
       - x86
           - libfoo.so
       - x86_64
           - libfoo.so

所以,在这种情况下搜索路径:path/to/lib/${ANDROID_ABI}/

要在项目中包含标题只需使用include_directories:

include_directories(path/to/headers)

4)。 .mk 文件仅在您使用 ndk-build 时才需要(所以您不需要任何文件)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-14
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 2016-05-23
    • 1970-01-01
    相关资源
    最近更新 更多