25、Android 移植C++ 開發的第三方.a包

基本思想:首先搭建一個Android的最基本工程,完成Android 調用c++ 的代碼;

                 然後本地寫一個c++的子模塊,使用配置好的(arm-linux-androideabi-gcc/g++)進行編譯得到.a

                最後將本地編譯的.a文件移植到Android工程上,完成Android-->c++ 工程---->(pc端交叉編譯的.a) 完成調用;

主要目的: 一是 可以本地開發模塊,直接導入Android 使用函數功能即可,二是 可編譯第三方開源庫,在Android中使用

第一步、首先建立一個基本的Android 工程,然後寫入Android調用c++ 的函數關係;

MainActivity 修改了默認的設置

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        // Example of a call to a native method
        //TextView tv = findViewById(R.id.sample_text);
        TextView tv = new TextView(this);
        testA aaa=new testA();
        String text=aaa.way();
        tv.setText(text);
        setContentView(tv);
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */

    public native int add(int a,int b,int []c);
}

testA文件內容

package com.example.myapplication;

public class testA {

    public String  way(){

        //tv.setText(stringFromJNI());
        int c[] ={1,2,3,4,5,6,7,8,8,9,9,1};
        int sum = add(2, 3,c);
        return "2 + 3 = " + Integer.toString(sum);
    }

    public native int add(int a,int b,int []c);
}

native-lib.cpp文件

#include <jni.h>
#include <string>
#include<iostream>

#include "info.h"
//#include <Eigen/Dense>
using namespace std;
extern "C" {


int total(int t,int g) {
    return t*g;
}



JNIEXPORT jint JNICALL
Java_com_example_myapplication_testA_add( JNIEnv*  env,
                                                  jobject  ,
                                                  jint a,
                                                  jint b,
                                                  jintArray arr)
{
    jint *carr;
    carr = env->GetIntArrayElements(arr, JNI_FALSE);

    if(carr == NULL) {
        return 0;
    }

    jint sum = 0;
    for(int i=0; i<10; i++) {
        sum += carr[i];
    }
    INFO *info= new INFO();
    int c=info->compute(a,b);
    delete info;
    int z=total(c,c);
    return (z+sum);
}

}

info.h頭文件

#ifndef MY_APPLICATION_INFO_H
#define MY_APPLICATION_INFO_H

class INFO
{

public:
    int compute(int a,int b);

};
#endif //MY_APPLICATION_INFO_H

info.cpp文件

//
#include "info.h"

int INFO::compute(int a,int b)
{

    return a+b;
}

CmakeLists.txt文件

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

# 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( # 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).
        native-lib.cpp
        info.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.

target_link_libraries( # Specifies the target library.
        native-lib

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

然後點擊允執行效果如下(使用sevensquare 連接手機,點擊Android stdio 運行,Android Stdio 環境配置自己解決)

 

然後在本第編譯XXX.a文件;首先在ubuntu 16.04 下載android-ndk-r14b-linux-x86_64.zip 建立交叉編譯器,

unzip android-ndk-r14b-linux-x86_64.zip
ubuntu@ubuntu:~/Downloads/android-ndk-r14b$ sudo ./build/tools/make-standalone-toolchain.sh --platform=android-19 --install-dir=/usr/local/bin/iot/android/ndk
[sudo] password for 10163374L: 
HOST_OS=linux
HOST_EXE=
HOST_ARCH=x86_64
HOST_TAG=linux-x86_64
HOST_NUM_CPUS=12
BUILD_NUM_CPUS=24
Auto-config: --arch=arm
Toolchain installed to /usr/local/bin/iot/android/ndk.



寫入環境變量 ~/.bashrc

sudo gedit ~/.bashrc

export PATH=$PATH:/usr/local/lib/iot/android/ndk/bin

source ~/.bashrc

查看編譯是否成功

ubuntu@ubuntu:~$ arm-linux-androideabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-androideabi-gcc
COLLECT_LTO_WRAPPER=/usr/local/lib/iot/android/ndk/bin/../libexec/gcc/arm-linux-androideabi/4.9.x/lto-wrapper

然後修改本地的CMakeLists.txt文件

 

aux_source_directory(. DIR_SUB_SRCS)

SET(CMAKE_C_COMPILER  /usr/local/lib/iot/android/ndk/bin/arm-linux-androideabi-gcc)
SET(CMAKE_CXX_COMPILER /usr/local/lib/iot/android/ndk/bin/arm-linux-androideabi-g++)

ADD_LIBRARY(static_lib STATIC ${DIR_SUB_SRCS}) 




ubuntu@ubuntu:~/project/src$ ls
CMakeLists.txt  function_1.cpp  function_1.h  function.cpp  function.h
ubuntu@ubuntu:~/project/src$ mkdir build
ubuntu@ubuntu:~/project/src$ cd build/
ubuntu@ubuntu:~/project/src/build$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.5)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /home/10163374L/project/src/build
10163374L@eytp-10163374l:~/project/src/build$ make
Scanning dependencies of target static_lib
[ 33%] Building CXX object CMakeFiles/static_lib.dir/function.o
[ 66%] Building CXX object CMakeFiles/static_lib.dir/function_1.o
[100%] Linking CXX static library libstatic_lib.a
[100%] Built target static_lib
ubuntu@ubuntu:~/project/src/build$ cls
No command 'cls' found, but there are 18 similar ones
cls: command not found
10163374L@eytp-10163374l:~/project/src/build$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  libstatic_lib.a  Makefile

四個文件具體內容 參考上一篇博客;生成Android的.a文件,導入Android Studio的lib 包中;修改Android 的CMakeLists.txt文件內容

待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章