Android Studio を利用して C++ のスタティックライブラリ(.a)をUnity(C#)向けに作成する
なにが学べるの?
Unity for Android の環境向けに、Android Studio を利用してスタティックライブラリを生成、使用するまでの方法を解説します。Android 向けにライブラリが公開されているものの、Unity 向けにまだ公開されていないような場合に、自身で Unity 向けにライブラリを使用するような場合に有用な知識です。
今回の知識を利用して、V8 エンジンを Android で動かしてみました。
環境
- Windows 10 Pro (ver. 21H2)
- Android Studio 2021.2.1
- Unity 2020.3.25f1
- Architecture - ARM64
GitHub で公開
今回の記事で実装したものを GitHub にあげてあるので、実際に動くもので確認したい方は clone
してお試しください。
Android Studio で空の新規プロジェクトを作成する
ここでは PluginTest
としました
C++ Module を追加する
開いたウィンドウで、左のペインから Android Native Library を選択し任意の名前を付けます。
ここでは cpplib
という名前にしました
追加されたモジュールを見ると自動的に CMakeLists.txt と cpplib.cpp ファイルが追加されています。
C++ を書く
まずはライブラリの元となる C++ コードを書いていきます。今回はかんたんな関数だけを定義しましょう。
extern "C" int Add(int a, int b)
{
return a + b;
}
関数を C# 側から呼び出せるようにするために extern "C"
を関数の頭に付けます。これは C リンケージと呼ばれるもので、C++ のコンパイル時に行われるマングリングを防ぐものです。かんたんな説明については前回の記事のマングリングを防ぐを参照ください。
CMake ファイルを編集する
次に、今回作成した C++ をビルドし、Unity 側で利用できるようにするために CMakeLists.txt を以下のように編集します。
追加・修正する部分のみを抜粋します。
# デフォルトで SHARED となっている部分を STATIC に変更する
add_library(cpplib STATIC cpplib.cpp)
# 書き出される場所を指定する
set(OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${CMAKE_ANDROID_ARCH_ABI})
set_target_properties(cpplib PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_DIR})
スタティックライブラリがビルドされるように設定する
build.gradle
を編集してスタティックライブラリがビルドされるように調整します。(使われないライブラリはデフォルトではビルドされません)
build.gradle
はプロジェクト内に複数存在しますが、今回編集するのは build.gradle (Module: PluginTest.cpplib)
です。
cmake
の項目に targets
を追加し、ライブラリ名を指定します。
defaultConfig {
...
externalNativeBuild {
cmake {
...
targets "cpplib"
}
}
}
ビルドする
ウィンドウメニューの Build > Make Module 'PluginTest.cpplib'
を実行してビルドします。
ビルドが成功したら以下の場所に .a
ファイルが生成されます。
/path/to/PluginTest2/cpplib/src/lib/{ARCH_ABI}/libcpplib.a
Unity にライブラリを追加
以下のように Plugins フォルダに作成したライブラリを追加します。追加する際、対象となる CPU のアーキテクチャが設定されているか確認してください。今回は ARM64 向けに作成、利用するので ARM64 に設定しています。
C# を書く
最後に、Unity の C# 側を書いていきましょう。といっても書くコード量は多くありません。適当なクラスを作成し、以下のコードを追加します。
using System.Runtime.InteropServices;
// -----------------------------------------
private const string LIB_NAME = "__Internal";
[DllImport(LIB_NAME)]
private static extern int Add(int a, int b);
DllImport
を利用して C++ 側の関数を指定します。注意点として C++ で作成されたライブラリは __Internal
を指定する必要があります。
あとは普通にビルドして関数を呼び出せば C++ 側の関数が実行され、正常に足し算されることが確認できます。
最後に
今回はシンプルな Add
関数だけの実装でしたが、C++ 側の処理を呼び出すことができました。冒頭に書いたような、既存ライブラリを Unity に移植する際は今回作成した手順を元に、ライブラリのラッパーを C++ で記述し、それを Unity で利用することで対応することができます。
実際に、今回のライブラリ制作を応用して冒頭の V8 エンジンを利用しています。
エンジニア絶賛募集中!
MESONではUnityエンジニアを絶賛募集中です! XRのプロジェクトに関わってみたい! 開発したい! という方はぜひご応募ください!
MESONのメンバーページからご応募いただくか、TwitterのDMなどでご連絡ください。
書いた人
比留間 和也(あだな:えど)
カヤック時代にWEBエンジニアとしてリーダーを務め、その後VRに出会いコロプラに転職。 コロプラでは仮想現実チームにてXRコンテンツ開発に携わる。 DAYDREAM向けゲーム「NYORO THE SNAKE & SEVEN ISLANDS」をリリース。その後、ARに惹かれてMESONに入社。 MESONではARエンジニアとして活躍中。
またプライベートでもAR/VRの開発をしており、インディー部門でTGSに出展など公私関わらずAR/VRコンテンツ制作に精を出す。プライベートな時間でも開発しているように、新しいことを学ぶことが趣味で、最近は英語を学んでいる。
MESON Works
MESONの制作実績一覧もあります。ご興味ある方はぜひ見てみてください。
Discussion