Introduction

Xamarinを再び勉強しはじめています。
Nativeのライブラリを使いたいので、試行錯誤中です。

Get Started!!

Androidで動作するNativeライブラリを作成するには、Android NDK (Native Development Kit) が必要です。
最初自分は g++ でできると思い込んで、それをAndroidのEmulatorに配置していたのですが、それは間違っていました(白目) なので、NDKの使い方から。

Download

公式のDownloadから入手します。
Windows、Mac、Linux用が提供されています。今回はWindows版を。

ダウンロードしたら、適当な場所に展開し、パスを通しておきます。
が、パスに空白が入ると動かないので注意。

パスを通したら

1
2
3
4
C:\WINDOWS\system32>ndk-build
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
C:\Android\NDK\build\\..\build\core\build-local.mk:151: *** Android NDK: Aborting

のように表示されれあば準備完了です。

Build

コンパイル環境ができましたので、ビルドを行います。
ビルドについては、

が非常に参考になりました。
ソースは下記です。
calc.cpp

1
#include "calc.h"

calc.h

1
2
3
4
5
6
7
8
9
10
11
#ifndef _CPP_CALC_H_
#define _CPP_CALC_H_

#include "export.h"

DLLEXPORT int calc_add(int a, int b)
{
return a + b;
}

#endif

export.h

1
2
3
4
5
#ifdef _WINDOWS
#define DLLEXPORT extern "C" __declspec(dllexport)
#else
#define DLLEXPORT extern "C"
#endif

次にビルドする際は、CMakeLists.txtのようなビルドの手順を示した

  • Android.mk
  • Application.mk

ファイルを用意します。

Application.mk

1
APP_PROJECT_PATH := $(NDK_PROJECT_PATH) APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/src/Android.mk

Android.mk

1
2
3
4
5
6
7
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := PInvokeApp.Native
LOCAL_SRC_FILES := calc.cpp

include $(BUILD_SHARED_LIBRARY)

これらを下記のような構成で展開します。

1
2
3
4
5
6
7
│  Application.mk

└─src
Android.mk
calc.cpp
calc.h
export.h

ここで、Application.mkにカレントディレクトリを移動して、下記のコマンドを実行することで、ライブラリが生成されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ ndk-build NDK_PROJECT_PATH=%cd% NDK_APPLICATION_MK=Application.mk
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-14.
[arm64-v8a] Compile++ : PInvokeApp.Native <= calc.cpp
[arm64-v8a] SharedLibrary : libPInvokeApp.Native.so
[arm64-v8a] Install : libPInvokeApp.Native.so => libs/arm64-v8a/libPInvokeApp.Native.so
[armeabi-v7a] Compile++ thumb: PInvokeApp.Native <= calc.cpp
[armeabi-v7a] SharedLibrary : libPInvokeApp.Native.so
[armeabi-v7a] Install : libPInvokeApp.Native.so => libs/armeabi-v7a/libPInvokeApp.Native.so
[x86] Compile++ : PInvokeApp.Native <= calc.cpp
[x86] SharedLibrary : libPInvokeApp.Native.so
[x86] Install : libPInvokeApp.Native.so => libs/x86/libPInvokeApp.Native.so
[x86_64] Compile++ : PInvokeApp.Native <= calc.cpp
[x86_64] SharedLibrary : libPInvokeApp.Native.so
[x86_64] Install : libPInvokeApp.Native.so => libs/x86_64/libPInvokeApp.Native.so

libsフォルダにアーキテクチャ毎にライブラリが生成されます。