AndroidStudio　モジュール内のC++を参照する(Java / kotlin)

Androidでライブラリー作成（AAR形式）はモジュールを作成することで実現します。
ただ、　モジュール内のC++ソース参照はめんどくさいので手順を残します。
■Setp1：プロジェクト作成
---

![2019-05-29 (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/04a3ad9b-c3c3-7865-d799-9f38b280d51a.png)
「File」「New」「New　Project」でプロジェクトを作成します。
![2019-05-29 (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/caf792bf-91d0-a1f3-e9d2-0c8f840ff9bf.png)
C++を使用するので。「Native C++」を選択し「Next」をおします。
![2019-05-29 (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/e68e44f1-dff5-1830-1748-96bbd88d2ca6.png)
今回はNameは「Test02」で
Save Locationは開発するディレクトリを指定
Languageは今回はJavaで（Kotlinでも大丈夫です）設定したら「Next」を
![2019-05-29 (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/6b6cf52f-8cf1-086c-78ed-d97bed1e7cc7.png)
あとは、そのまま「Finish」を
![2019-05-29 (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/705350b0-fc37-6bae-7a35-3234248038b1.png)
こんな画面になればプロジェクト作成できています。

■Setp2；モジュール作成
---

![2019-05-29 (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/4e300d2d-919f-68ad-e6cb-7fd3a706aae5.png)
Setp1で作ったプロジェクトにモジュールを追加します。
「File」「New」「New　Modile」を選択してください。
![2019-05-29 (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/a112c411-3fad-d6f9-e0c3-b052404dafb2.png)
今回は「Android Library」を選択し、「Next」を
![2019-05-29 (19).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/e91044bb-2ec3-29b4-5c41-93da0d0f8a3e.png)
Application/Library nameは今回は「test02module」にしています。
「Finish」を押せば
![2019-05-29 (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/f8c610c5-3e66-0817-72ef-87698c1656b8.png)
こんな感じになり、「test02module」がプロジェクトに追加されたことがわかります。

■Setp3：モジュールにC++のソースを追加。
---

まず、C++のソースを置くディレクトリを作成します。
[test02]
+---[test02modile]
　　+---[src]
　　　　+---[main]
　　　　　　+---[cpp] (このディレクトリを作成）
そこに「CMakeList.txt」「subTest.cpp」「subTest.h」　を作成します。

```text:CMakeList.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-module

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        subTest.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)

set( LIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../.. )
set( OUTPUT_DIR ${LIB_ROOT}/lib/${ANDROID_ABI} )
set_target_properties( native-module
        PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIR} )

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

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
```
```c++:subTest.cpp
#include "subTest.h"

subTest::subTest() {
}

void subTest::Hoge(int in_no) {
    int a = in_no;
}
```
```c++:subTest.h
#pragma once

class subTest{
public:
    subTest();
public:
    void Hoge(int in_no);
};
```
この三ファイルを追加したらbuild.gradle(Module:test02module)を編集します。
![2019-05-29 (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/16ff7275-3bae-a3fc-9c67-128cd74d241e.png)

```:build.gradle
android {
　　　：
　　　：
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}
```

を追加します。
これでいったんSyncさせると
![2019-05-29 (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/db7cce5b-7dc0-65ef-fc0c-e1d91f1ec7db.png)
ファイルがModuleに追加されたことがわかります。

■Setp4:アプリのCからモジュールのCを呼び出す。
---

アプリ側のbuild.gradle(Module:app)を編集します。
![2019-05-29 (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/015aa169-d852-0b73-2248-90440154e227.png)

```
android {
　　：
　　：
    sourceSets {
        main {
            jniLibs.srcDir '../test02module/src/lib'
            jni.srcDirs = []
        }
    }
}
```

これで、C++のライブラリsoファイルを参照できるようにします。
アプリ側の「CMakeKists.txt」を編集します。
![2019-05-29 (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/6ac11965-f39c-db4d-1ed7-aeb0ff7ee3b6.png)

```text:CMakeKists.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)

include_directories(../../../../test02module/src/main/cpp)

add_library( native-module
        SHARED
        IMPORTED )
set_target_properties( native-module
        PROPERTIES IMPORTED_LOCATION
        ../../../../../test02module/src/lib/${ANDROID_ABI}/libnative-module.so)

# 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
        native-module
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
```

これで、参照可能になったので。 アプリのCのソースをnative-lib.cpp

```c++:native-lib.cpp
#include <jni.h>
#include <string>

#include "subTest.h"

extern "C" JNIEXPORT jstring JNICALL
Java_l_toox_test02_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    subTest ss;
    ss.Hoge(32);
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
```

で参照できます。

■Step5：コンパイルエラー
---

そのままコンパイルするとエラーになるときがあります。
それはsoファイルが作成されてないかもしれないので
![2019-05-29 (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122121/3b429a6b-11e7-831f-3fbd-cabaf8e6c740.png)
「test02modile」を選択したあとに「Build」を選択すると「Make Moduke 'test02module'」があらわれるので実行してから、アプリを実行すると問題ないです。