使用Android NDK实现.a库时出现问题。函数抛出未定义符号错误。

huangapple go评论153阅读模式
英文:

Problem with .a library implementation using Android NDK. Functions throw undefined symbol error

问题

I understand that you'd like a translation of the code and error message provided. Here is the translated code snippet:

#include <jni.h>
#include "es_rgil.h"

extern "C" JNIEXPORT int32_t JNICALL
Java_com_bartosz_lewandowski_libraryconnector_MainActivity_mifareAuth(JNIEnv *env,
                                                                      jobject /* this */,
                                                                      jbyte sector,
                                                                      jboolean keyType,
                                                                      jbyte key,
                                                                      jsize len) {

    es_rgil_mifare_key_type k_type = ES_RGIL_MIFARE_KEY_A;
    if (keyType) {
        k_type = ES_RGIL_MIFARE_KEY_B;
    }

    return es_rgil_mifare_auth(static_cast<uint8_t>(sector), k_type, reinterpret_cast<const uint8_t*>(key), len);
}

Your CMakeLists.txt file remains the same, and the error message you provided indicates an "undefined symbol" error, which means the linker can't find the es_rgil_mifare_auth function. Ensure that your library (libes_rgil.a) is correctly linked and contains the necessary symbols.

If you have any specific questions or need further assistance, please let me know.

英文:

I'm completely new to NDK (and C/C++) so I'm sorry if the question may be too elemental. I have a problem thrying to import to my Android Kotlin project a library written in C.
I'm not sure if the problem is in my CmakeLists file or in trying to convert C variable types to JNI or JNI to Kotlin. Or I'm doing something wrong with linking header with .a file? I have a header file named es_rgil.h and a static library librgil.a. Android Studio sees this library becouse it suggested to create functions colors my code in every file.

I'll be very grateful for any advice or solution. I'm strugeling with this for a week and getting crazy...

In the header there is a function which looks like: int32_t es_rgil_mifare_auth(const uint8_t sector, const es_rgil_mifare_key_type key_type, const uint8_t *key, const size_t key_size);

My native-lib.cpp file which is my bridge between C and kotlin looks like this:

#include &lt;jni.h&gt;
#include &quot;es_rgil.h&quot;

extern &quot;C&quot; JNIEXPORT int32_t JNICALL
Java_com_bartosz_lewandowski_libraryconnector_MainActivity_mifareAuth(JNIEnv *env,
                                                                      jobject /* this */,
                                                                      jbyte sector,
                                                                      jboolean keyType,
                                                                      jbyte key,
                                                                      jsize len) {

    es_rgil_mifare_key_type k_type = ES_RGIL_MIFARE_KEY_A;
    if (keyType) {
        k_type = ES_RGIL_MIFARE_KEY_B;
    }

    return es_rgil_mifare_auth((uint8_t )sector, k_type, reinterpret_cast&lt;const uint8_t *&gt;(key), len);
}

In my activity file export function looks like: external fun mifareAuth(sector: Byte, isKeyTypeB: Boolean, key: Byte, len: Int): Int

CMakeLists looks like this:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.22.1)

# Declares and names the project.

project(libraryconnector)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library(
        es_rgil
        STATIC
        es_rgil.h
)

add_library( # Sets the name of the library.
        libraryconnector

        # Sets the library as a shared library.
        SHARED

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

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

#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)

# 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.
set_target_properties(es_rgil PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries( # Specifies the target library.
        libraryconnector
        es_rgil)
        # Links the target library to the log library
        # included in the NDK.
#        ${log-lib})

Error:

cmd.exe /C &quot;cd . &amp;&amp; D:\AndroidSDK\ndk.1.8937393\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android24 --sysroot=D:/AndroidSDK/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security  -std=c++11 -fno-limit-debug-info  -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--gc-sections -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,liblibraryconnector.so -o C:\Users\barte\AndroidStudioProjects\LibraryConnector\app\build\intermediates\cxx\Debug4i55q5\obj\arm64-v8a\liblibraryconnector.so CMakeFiles/libraryconnector.dir/native-lib.cpp.o  libes_rgil.a  -latomic -lm &amp;&amp; cd .&quot;

ld: error: undefined symbol: es_rgil_mifare_auth
&gt;&gt;&gt; referenced by native-lib.cpp:26 (C:/Users/barte/AndroidStudioProjects/LibraryConnector/app/src/main/cpp/native-lib.cpp:26)
&gt;&gt;&gt;               CMakeFiles/libraryconnector.dir/native-lib.cpp.o:(Java_com_bartosz_lewandowski_libraryconnector_MainActivity_mifareAuth)

cmd.exe /C &quot;cd . &amp;&amp; D:\AndroidSDK\ndk.1.8937393\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android24 --sysroot=D:/AndroidSDK/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security  -std=c++11 -fno-limit-debug-info  -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--gc-sections -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,liblibraryconnector.so -o C:\Users\barte\AndroidStudioProjects\LibraryConnector\app\build\intermediates\cxx\Debug4i55q5\obj\arm64-v8a\liblibraryconnector.so CMakeFiles/libraryconnector.dir/native-lib.cpp.o  libes_rgil.a  -latomic -lm &amp;&amp; cd .&quot;

clang++: error: linker command failed with exit code 1 (use -v to see invocation)

I tried different combinations of variable types, different aproaches to write CMakeLists file.

答案1

得分: 0

你正在寻找的概念是一个导入目标:

add_library(es_rgil STATIC IMPORTED)
set_property(TARGET es_rgil PROPERTY IMPORTED_LOCATION "librgil.a")

第二行告诉CMake实际的代码在哪里,以及它应该如何被合并到你的主目标库中。

你还可以选择使用 target_include_directories 来告诉CMake头文件位于哪里,就像这样:

target_include_directories(es_rgil INTERFACE some/subdir/rgil)
英文:

The concept you are looking for is an IMPORTED target:

add_library(es_rgil STATIC IMPORTED)
set_property(TARGET es_rgil PROPERTY IMPORTED_LOCATION &quot;librgil.a&quot;)

The second line tells CMake where the actual code is and how it should be incorporated into your main target's library.

You can optionally use target_include_directories to tell CMake where the header file lives like so:

target_include_directories(es_rgil INTERFACE some/subdir/rgil)

huangapple
  • 本文由 发表于 2023年6月11日 21:50:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450788.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定