android studio project

时间:2018-02-04 18:19:12

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

正如标题所示我试图将本地.so链接到android工作室项目。我已经浏览了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 lib进行了编码,当我这样做时,android studio会抛出上述错误。我的实际目标是根据手机中的芯片动态加载库。我很确定我目前的代码没有实现这一点。

以下是我的查询

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

  2. 如何将.so.h文件添加到本机android工作室项目中?这有基于代码运行的芯片的变化?

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

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

2 个答案:

答案 0 :(得分:1)

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时才需要(因此您不需要)

答案 1 :(得分:0)

在您的情况下,您不需要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) 。对于日志,NDK会为您解析库;对于 libremotedesktop_client.so ,您知道确切的路径。

以下是适合您的 CMakeLists.txt

${CMAKE_CURRENT_SOURCE_DIR}

请注意,在CMake脚本中使用完整路径( E:/ project ... )不是最佳做法;您可能会以某种方式表达相对于 CMakeLists.txt 路径的此库的路径,即const { client } = require('nightwatch-cucumber') const { defineSupportCode } = require('cucumber') const globals = require('../../config/globals.js') var emailEntry = (`input[name='administrator[email]']`) var passwordEntry = (`input[name='administrator[password]']`) var existingGtmKey = ("GTM-123456") var newGtmKey = ("GTM-654321") var gtmKey = (`//div/input[@value='${existingGtmKey}']`) var saveButton = (`input[type=submit][value='Save']`) defineSupportCode(({ Given, Then, When }) => { Given(/^I've logged into Winit cms$/, () => { return client .url('http://winit-stage.bauerpublishing.com/admin/sign_in') .waitForElementVisible('body', 5000) // Enter winit email address .moveToElement(`form#new_administrator ${emailEntry}`, 1,1) .click(`form#new_administrator ${emailEntry}`) .setValue(`${emailEntry}`, "*****.*****@*****.co.uk") // Enter winit password .moveToElement(`form#new_administrator ${passwordEntry}`, 1,1) .click(`form#new_administrator ${passwordEntry}`) .setValue(`${passwordEntry}`, "******") // Click on the 'Sign in' button .click("form#new_administrator input[type=submit][value='Sign in']") }) Then (/^I'm able to change the gtm tag for that site (.*?)$/, (siteedit) => { return client // Click on the 'sites' link .useXpath() .click("//a[normalize-space(text())='Sites']") // Click on Edit button .click(siteedit) .click(`${gtmKey}`) .clearValue(`${gtmKey}`) // Set new gtm key value .setValue(`${gtmKey}`, `${newGtmKey}`) // Click save .useCss() .click(`${saveButton}`) }) })