首页 > 解决方案 > 我想通过android调用c语言,通过c语言调用汇编语言,但是出现undefined reference to `MyASMTest(int, int)'

问题描述

我想通过android调用c语言,通过c语言调用汇编语言,但是出现了

undefined reference to `MyASMTest (int, int) '

具体错误是这样的任务':app:externalNativeBuildDebug'的执行失败

这是我的native-lib.cpp

#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#define  __x86_64__

#ifndef __x86_64__
    static int __attribute__((naked, pure)) MyASMTest(int a, int b)
    {
        #ifndef __arm__
            asm("add w0, w0, w1");
            asm("ret");
        #else
            asm(".thumb");
            asm(".syntax unified");
            asm("sub r0, r0, r1");
            asm("add r0, r0, #1");  
            asm("bx lr");
        #endif
    }
#else

extern int MyASMTest(int a, int b);

#endif



extern "C"
JNIEXPORT JNICALL jstring Java_com_example_cpptest_MainActivity_stringFromJNI (JNIEnv *env, jobject instance)
{
    char strBuf[128] = {' '};
    sprintf(strBuf, "Hello from C! ASM test result: %d", MyASMTest(4,6));
    return env->NewStringUTF(strBuf);
}

这是我的CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)
enable_language(ASM_NASM)

if(${ANDROID_ABI} STREQUAL "x86_64")
    set(asm_SRCS src/main/cpp/test.asm)
endif()

add_library( 
             native-lib
             SHARED
             native-lib.cpp )

find_library( 
              log-lib
              log )
target_link_libraries( 
                       native-lib
                       ${log-lib} )

这是我的gradle

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    defaultConfig {
        applicationId "com.example.cpptest"
        minSdkVersion 24
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_ARM_NEON=TRUE"
                cppFlags ""
                abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
            }
        }
        dataBinding{
            enabled true
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

这是我的test.asm

global MyASMTest

section .text

MyASMTest:

    sub     edi, esi
    mov     eax, edi
    ret

这是我的错误信息

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:externalNativeBuildDebug'.
> Build command failed.
  Error while executing process C:\Users\user\AppData\Local\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C F:\Users\user\Desktop\aaaaaaaaaaaaaaaaaaa\CppTest\app\.cxx\cmake\debug\arm64-v8a native-lib}
  ninja: Entering directory `F:\Users\user\Desktop\aaaaaaaaaaaaaaaaaaa\CppTest\app\.cxx\cmake\debug\arm64-v8a'
  [1/2] Building CXX object CMakeFiles/native-lib.dir/native-lib.cpp.o
  [2/2] Linking CXX shared library F:\Users\user\Desktop\aaaaaaaaaaaaaaaaaaa\CppTest\app\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so
  FAILED: F:/Users/user/Desktop/aaaaaaaaaaaaaaaaaaa/CppTest/app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so 
  cmd.exe /C "cd . && C:\Users\user\AppData\Local\Android\Sdk\ndk\21.0.6113669\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android24 --gcc-toolchain=C:/Users/user/AppData/Local/Android/Sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=C:/Users/user/AppData/Local/Android/Sdk/ndk/21.0.6113669/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   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libnative-lib.so -o F:\Users\user\Desktop\aaaaaaaaaaaaaaaaaaa\CppTest\app\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/native-lib.cpp.o  -llog -latomic -lm && cd ."
  CMakeFiles/native-lib.dir/native-lib.cpp.o: In function `Java_com_example_cpptest_MainActivity_stringFromJNI':
  F:/Users/user/Desktop/aaaaaaaaaaaaaaaaaaa/CppTest/app/src/main/cpp/native-lib.cpp:76: undefined reference to `MyASMTest(int, int)'
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.

想测试一下如何在Android中使用汇编,但是发现自己对arm32汇编不熟悉,所以想切换到x86汇编,所以就用了上面的#defind__x86_64__。如果#defind x86_64软件被删除,该软件可以成功执行。所以我想知道如何让我的软件成功执行x86汇编代码,因为我对x86比对arm32更熟悉

标签: androidcassemblycmake

解决方案


推荐阅读