概要
サーバー連携をする際に送る認証用データを作ったりしたくて、そういった箇所はリコンパイルが(比較的)難しいC++側で作り込みたいなと思ったのでそのやり方をまとめます。
まずはC++の簡単なファイルを作ってのUnity連携までを記載します。
なお、連携部分は以下を大いに参考にさせていただきました。
Unity iOS/Android共用プラグイン C++ライブラリ作成
https://qiita.com/satotin/items/05fad323de3101f775d5
動作環境
- Mac OSX (10.15.4)
- Xcode 11.4.1
- Android Studio 3.5
- Android NDK r17b
- Crypto++ 8.2.0
- Unity 2019.3.13f1
Unityプロジェクトの作成
とりあえず、サクっとUnityプロジェクトを作成します。こちらは割愛。
Assetsフォルダ直下に必要なフォルダを作成
以下になるように、Assetsフォルダ内にフォルダを作成していきます。
■ Assets
├ ■ Plugins: ネイティブ側の連携ソースを入れる
| ├ ■ iOS: iOSのビルド済のFrameworkを格納
| └ ■ Android: Androidのビルド済のsoファイルを格納
└ ■ Scripts: C#のスクリプトを格納
■ src: C++のビルドする環境などを格納
└ ■ CppBridge: C++のソースファイルを格納 (名前は何でもいいですが以下はこの前提で記載しています)
srcファイルは、Assetsの外側に配置します(そうしないと中のC++ファイルもビルド時に取り込まれちゃう)。
src 直下に Static Library を作成
とりあえずC++をいじるのにXcodeの環境を使っていきます。ということでStatic Libraryを作成します。
LanguageはSwiftだとC++連携も面倒なのでObjective-cにします。
とはいってもObjective-c は特には使わないから何でもいいんですが。
iOS側のビルド設定
Deployment Targetを 8.0
にします。
その後、Build Settingsより、以下を変更します。
Supported Platforms: iphoneos
Build Active Architecture Only : Debug / Releaseともに YES
Valid Architectures: arm64 armv7 armv7s
Android側のビルド設定
src直下に以下をそれぞれ作成します。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := CppBridge_shared
LOCAL_MODULE_FILENAME := libcppbridge
LOCAL_CFLAGS := -Werror
CPP_FILES := $(shell find $(LOCAL_PATH)/CppBridge -name *.cpp)
CPP_FILES += $(shell find $(LOCAL_PATH)/CppBridge -name *.c)
LOCAL_SRC_FILES += $(CPP_FILES:$(LOCAL_PATH)/%=%)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/CppBridge
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
APP_STL := c++_static
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -std=c++11 -fsigned-char -Wno-extern-c-compat
APP_LDFLAGS := -latomic
APP_OPTIM := debug
APP_ABI := armeabi-v7a arm64-v8a x86
APP_PLATFORM := android-14
APP_BUILD_SCRIPT := Android.mk
ビルドスクリプトの作成
Xcodeビルド時にiOS / Androidの両方ともビルドされるようにBuild Phases -> Run Scriptに処理を追加します。
# iOSの成果物を移動
mv -f $TARGET_BUILD_DIR/libCppBridge.a $SRCROOT/../Assets/Plugins/iOS
# Androidの実行プログラム作成&移動
ANDROID_NDK_ROOT=<Android_NDKのパス>
$ANDROID_NDK_ROOT/ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=$SRCROOT/Application.mk $*
rm -rf $SRCROOT/../Assets/Plugins/Android/**
mkdir $SRCROOT/../Assets/Plugins/Android/libs
mv -f $SRCROOT/libs/** $SRCROOT/../Assets/Plugins/Android/libs/
rm -rf $SRCROOT/libs
rm -rf $SRCROOT/obj
ビルド時の動作確認
ひとまず、簡単なC++のファイルを作ってビルドをしてみます。
https://qiita.com/satotin/items/05fad323de3101f775d5 に記載の内容をそのまま使わせていただきました。
#ifndef NativeBridge_hpp
#define NativeBridge_hpp
extern "C" {
int test();
}
#endif /* NativeBridge_hpp */
#include "NativeBridge.hpp"
#include <stdio.h>
#ifdef __ANDROID__
#include <android/log.h>
#endif
int test(){
#ifdef __ANDROID__
__android_log_write(ANDROID_LOG_DEBUG, "hello.cpp", "Hello,World!");
#else
printf("Hello,World!\n");
#endif
return 0;
}
XcodeでRunして、以下のように表示されてたら(多分)成功です。
その際、Unityへの配置は以下のようになります。
ちなみに、実行時にこんなのが出る場合、セキュリティでXcodeを許可するようにしましよう。
Unity側での動作確認
そんなわけで、いよいよUnityでの動作確認を行います。
その前に、配置された実行ファイルのプラットフォームが正しく設定されているかどうかを確認します。
Android側
いずれの実行ファイルも Android
にだけチェックがついてたらOKです。
iOS側
iOS
にだけチェックがついてたらOKです。
C#のソース作成
こちらも、 以下を大いに参考にさせてもらいました(というかほぼコピペさせてもらいました)
https://qiita.com/satotin/items/05fad323de3101f775d5
using UnityEngine;
public class PluginCall : MonoBehaviour {
// Start is called before the first frame update
void Start() {
}
// Update is called once per frame
void Update() {
}
public void OnClickedButton() {
Debug.Log("OnClickedButton");
Plugins.NativeBridge.HelloTest();
}
}
上記は、適当なボタンにアタッチしてOnClickedButtonが呼ばれるようにしておきます。
using UnityEngine;
using System.Runtime.InteropServices;
namespace Plugins {
public class NativeBridge {
#if UNITY_IOS || UNITY_ANDROID
#if UNITY_IOS
[DllImport ("__Internal")]
#elif UNITY_ANDROID
[DllImport ("CppBridge")]
#endif
private static extern int test();
#endif
public static int HelloTest() {
#if UNITY_EDITOR
Debug.Log("Call Native");
return 1;
#else
return test();
#endif
}
}
}
一応はUnity Editorでも動かせるように適当な値を返すようにしてます。
実機ビルド
あとは、実機でビルドします。
iOS側は以下のように表示されました。
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 35)
Hello,World!
Android側のLogCatもこんな感じで表示されます。
05-10 20:46:00.171 20232 20261 D hello.cpp: Hello,World!