在android studio项目中链接.so库

Nir*_*Raj 6 c++ android shared-libraries android-ndk

正如标题所暗示的,我正在尝试将本机链接.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()
Run Code Online (Sandbox Code Playgroud)

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

这是我的疑问

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

  2. 如何将一个.so和一个.h文件添加到本机 android studio 项目中?根据运行代码的芯片有变化吗?

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

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

Ale*_*ohn 6

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

\n\n

这是适合您的CMakeLists.txt :

\n\n
cmake_minimum_required(VERSION 3.4.1)\n\nadd_library( # Sets the name of the library.\n             native-lib\n\n             # Sets the library as a shared library.\n             SHARED\n\n             # Provides a relative path to your source file(s).\n             src/main/cpp/native-lib.cpp )\n\nadd_library(remote SHARED IMPORTED)\n\nset_property(TARGET remote PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/${ANDROID_ABI}/libremotedesktop_client.so")\n\n# Specifies libraries CMake should link to your target library. You\n# can link multiple libraries, such as libraries you define in this\n# build script, prebuilt third-party libraries, or system libraries.\n\ntarget_link_libraries( # Specifies the target library.\n                       native-lib\n\n                       # Links the target library to the log library\n                       # included in the NDK.\n                       log\n\n                       remote)\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,在 CMake 脚本中使用完整路径 ( E:/project\xe2\x80\xa6 ) 并不是最佳实践;您可能可以以某种方式相对于CMakeLists.txt的路径(即${CMAKE_CURRENT_SOURCE_DIR}.

\n


Van*_*ken 3

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

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()
Run Code Online (Sandbox Code Playgroud)

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

- path/to/lib
       - armeabi-v7a
           - libfoo.so
       - arm64-v8a
           - libfoo.so
       - x86
           - libfoo.so
       - x86_64
           - libfoo.so
Run Code Online (Sandbox Code Playgroud)

因此,本例中的搜索路径:path/to/lib/${ANDROID_ABI}/

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

include_directories(path/to/headers)
Run Code Online (Sandbox Code Playgroud)

4). 仅当您使用时才需要 .mk 文件ndk-build(因此您不需要任何文件)