はじめに
私はUnity開発者です。C++のライブラリをUnityで動かしてよと言われたので勉強中です。
手順を記載していきますが、内容については深く触れません。
作業したプロジェクトはこちらになります。わかりづらい部分はこちらを参考にしてください。
https://github.com/Kazu-num/CppToUnity
PCはMac(M1)を使いました。今回は簡単な処理のビルドになりますが、C++ライブラリのビルドになってくると第三者のビルドツールや手順にお世話になることが多く、Mac/Linuxユーザーが多い印象です。
C++をAndroid NDKでビルド
Cmakeを使う方法など他の方法もありますが、
今回はmakeファイルを使った方法を採用します。
AndroidNDKのインストール
今回は最新のr25を使用しますが、ビルドしたいライブラリによってはNDKのバージョンが指定されていることが多いので注意してください。
https://developer.android.com/ndk/downloads?hl=ja
古いバージョンを使用する場合はこちらからインストールできます。
https://github.com/android/ndk/wiki/Unsupported-Downloads
※上記にも記載されていないほど古いバージョン(r8など)も、URLを手直しするとDLできたりします。
利用規約に同意してダウンロードすると、最新のバージョンだと.dmgのイメージファイルが手に入ると思います。
手に入れたNDKを使いやすい位置に配置します。
私は「/Users/${Username}/Tools」の位置にAndroidNDKフォルダを作りました。
mkdir ~/Tools
cd ~/Tools
mkdir AndroidNDK
cd AndroidNDK
NDKが.dmgの場合はここにアプリケーションファイルをドラッグ&ドロップします。
NDKの場所を環境変数に指定します。
.dmgの場合はFinder上で右クリックして「パッケージの内容を表示」を押すとアプリケーションファイルの中を見ることができます。
ndk-buildを使いたいので格納されているフォルダを探してください。
r25では「/Users/${Username}/Tools/AndroidNDK/AndroidNDK9519653.app/Contents/NDK」にありました。
NDKの場所は一般的にANDROID_NDKとして指定しますが、今回はNDKのバージョンを変えやすいようにANDROID_NDK25として指定しました。
ndk-buildが動作するか一度確認します。
NDKがアプリケーションファイルの場合は動かす前に一度ダブルクリックで開いてください。
インターネットからダウンロードしたアプリに対する警告が出ます。開くを押しましょう。
下記のようなコマンドでndk-buildが動くか確認します。
$ANDROID_NDK25/ndk-build -v
今回ビルドするC++コード
extern "C" {
int nativeAdd(int a, int b)
{
return a + b;
}
}
ただの足し算です。
makeファイルを作成
ドキュメントに従って、2つファイルを作成します。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := CppToUnity
LOCAL_SRC_FILES := CppToUnity.cpp
include $(BUILD_SHARED_LIBRARY)
参考:https://developer.android.com/ndk/guides/android_mk?hl=ja
APP_ABI := arm64-v8a
参考:https://developer.android.com/ndk/guides/application_mk?hl=ja
build
今回は次のようなフォルダ構成で各ファイルを配置します。
Android
|- jni
|- Android.mk
|- Application.mk
|- CppToUnity.cpp
Androidフォルダでndk-buildを実行します。
$ANDROID_NDK25/ndk-build
Androidフォルダ以下にlibs、objフォルダが出来ていれば成功です。
Android/libs/arm64-v8a/libCppToUnity.soをUnityで使います。
Unityで使ってみる
Unity2021.3.19f1を使用しました。
ProjectSettings
Native処理を利用するので、OtherSettings > ScriptCoplilationのAllow 'unsafe' Codeにチェックを入れます。
arm64-v8aを使用したいので、OtherSettings > ConfigurationのScriptingBackendをIL2CPPに、Target ArchitecturesをARM64にします。
C++ライブラリを配置する
Assets/Plugins/Android/armeabi-v8a/libCppToUnity.soとなるように、配置します。
libCppToUnity.soのInspectorでPlatformがAndroid、CPUがARM64になっていることを確認します。
C#スクリプトを書く
ライブラリの処理を呼び出すスクリプトを書きます。
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;
public class CppToUnity : MonoBehaviour
{
[SerializeField]
InputField inputFieldA;
[SerializeField]
InputField inputFieldB;
[SerializeField]
Text anserText;
public void Calc()
{
var aIsInt = int.TryParse(inputFieldA.text, out int a);
var bIsInt = int.TryParse(inputFieldB.text, out int b);
if (aIsInt && bIsInt)
{
// anserText.text = (a + b).ToString();
var ans = nativeAdd(a, b);
anserText.text = ans.ToString();
Debug.LogFormat("{0} + {1} = {2}", a, b, ans);
}
}
[DllImport("CppToUnity")]
private static extern int nativeAdd(int a, int b);
}
※Editor実行するとDllNotFoundのエラーが出ます。動作は実機で確認してください。
C++の処理を呼び出しているのはここになります。
[DllImport("CppToUnity")]
private static extern int nativeAdd(int a, int b);
シーンの実装・ビルド
省略します。はじめに記載したGitHubの”CppToUnity”フォルダのUnityプロジェクトを参考にしてください。
足し算出来てます。
最後に
正直ほとんど理解しきれていませんが、まずは第一歩ということで足し算が出来ました。
これから理解を進めてOSSライブラリをビルドしていかないといけません。
ビルドマスターに俺はなる...!