概要
UnityでC++を呼び出し、さらにOSの機能を使用するためにSwiftを使用する方法について調べたので備忘録として残します。
また、SwiftからC++のコールバックを呼び出すための方法についても調べました。
前提
- macOS Big Sur バージョン11.6.2
- Xcode バージョン13.2.1
- Unity 2019.4.19
内容/手順
C++ Static LibraryとiOS Native Pluginを作成し、Unityに組み込んで使用できることを目指します。
UnityでiOS Native Pluginを使用する方法については以下の記事を参考にさせていただきました。
https://qiita.com/fuziki/items/955c2b35514bcfc37969
1. SwiftのFrameworkを作成する
Swift Package Managerを使用し、Frameworkを作成する。
①typeにlibrary、nameにSwiftPluginを指定しパッケージを初期化する。
swift package init --type=library --name=SwiftPlugin
②パッケージの作成後、Package.swiftを開く。
open Package.swift
③Swiftで関数を作成する
c++のコールバックを登録する関数を作成します。
public typealias Callback = @convention(c) (UnsafePointer<CChar>?) -> Void
cppCallback: Callback? = nil
@_cdecl("registCppCallback")
public registCppCallback(_ callback: @escape Callback) {
cppCallback = callback
}
次に、コールバックを呼び出す関数を作成します。
@_cdecl("cppCallbackFromSwift")
public func cppCallbackFromSwift() {
let str = "Swift Message."
cppCallback!(str)
}
ここでは@_cdeclを使用し、Cの関数として定義します。
これによってC++から直接呼び出すことができるようになります。
④Frameworkをビルドする
xcodeprojを作成します。
swift package generate-xcodeproj --skip-extra-files
次に、xcodebuild を使って出力した xcodeproj から framework を作成します。
CONFIGURATION_BUILD_DIR に指定したディレクトリに、.framework 作成されます。
xcodebuild -project SwiftPlugin.xcodeproj -scheme SwiftPlugin-Package -configuration Release -sdk iphoneos CONFIGURATION_BUILD_DIR=.
指定したディレクトリにSwiftPlugin.frameworkが作成されていれば成功です。
2. C++ Static Libraryを作成する
Swiftと連携するためのC++の処理を作成します。
③C++で関数を作成する
#ifdef __cplusplus
extern "C" {
#endif
void registCppCallback(void (*fun)(const char*));
void cppCallbackFromSwift();
void registCallback();
void PrintMessage();
#ifdef __cplusplus
}
#endif
void printFunc(const char* str) {
std::cout << str << std::endl;
}
void registCallback() {
registCppCallback(printFunc);
}
void PrintMessage(){
cppCallbackFromSwift();
}
#endif
②Static Libraryをビルドする
Static Libraryのビルドを行い、.aファイルを作成します。
3. C#の処理を作成する
C#からC++を呼び出すための処理を作成します。
[DllImport("__Internal")]
private static extern void registCallback();
[DllImport("__Internal")]
private static extern void PrintMessage();
void Start()
{
registCallback();
}
void Update()
{
// 呼び出し
PrintMessage();
}
4. Unityでビルドを行う
Unityに前述で作成した.aとSwiftPlugin.frameworkをPlugins/iOS/に追加し、ビルドを行います。
この時、SwiftPlugin.framework の Inspector で、Add To Embedded Binaries を有効にします。これにより、ビルドしたときに Framework が自動で Embed され ます。
5. Xcodeでのビルド・実行確認
出力されたxcodeprojectをXcodeでビルドし、実機確認を行います。
無事C++コールバックが呼ばれていたら成功です。