iPhone/AndroidアプリでCライブラリを呼び出す構成。どうすれば簡単に作れるのか?
2020/01/04 - moriya - ~4 Minutes
あるC言語で書かれたライブラリを、iPhone、Android のアプリから呼び出して使いたいという案件。
Android の場合、Java + C ライブラリ、iPhone の場合、Swift + C ライブラリで実現できることは実証済みだったのだが、UI の部分や、C 言語へ渡す部分、またデータをJava/Swift側で暗号化していて、暗号化する部分は、Java/Swift側に持っている(Cライブラリでやろうとすると大変なので)といった構成になっていて、両方のプラットフォームのコードをメンテナンスするのは、非常にめんどうだ。また、私1人でやるので、共通のコードでメンテナンスできないものか・・・と思っていた。
前々から調べようと思っていたのだが、Xamarin Forms を使えば、Android / iPhone 両方のアプリが開発できそうだ。Flutter などどうかとも聞かれたが、ドキュメントをさらっと見た限り、Xamarin Forms のほうが Cライブラリの組み込みが簡単そうなのと、身近に C# の案件などがありそう(需要が多い?)なので、Xmarin Forms でトライさせてもらうことにした。
Cライブラリをリンクするにあたって参考になったページは以下のページだ。
- https://docs.microsoft.com/ja-jp/xamarin/cross-platform/cpp/
- https://github.com/xamcat/mobcat-samples/tree/master/cpp_with_xamarin
要は、C / C++ライブラリをコンパイルし、C# の関数からそのライブラリを呼び出すラッパーを作り、nuget パッケージを作る。
私は、 https://github.com/xamcat/mobcat-samples/blob/master/cpp_with_xamarin/Sample/MathFuncsLib/Build/MathFuncsLib.sh のシェルスクリプトを流用し、ソースを一箇所に集めてきてコンパイルし、ライブラリを作った。*.c (*.cpp) でコンパイルするのはどうかと思うので、makefile を作るか、cmake を使ったほうが良いかもしれない。
https://github.com/xamcat/mobcat-samples/tree/master/cpp_with_xamarin/Sample/Consumer/MathFuncsApp を参考にラッパーを作った。
https://github.com/xamcat/mobcat-samples/tree/master/cpp_with_xamarin#creating-the-package に書かれているような感じで、nuget パッケージを作る。
nuget パッケージができたら、アプリのプロジェクトから nuget パッケージを登録すればよい。nuget パッケージは、ローカルに置くこともできるので、ライブラリとして渡すのが簡単なのではないだろうか・・・
ちなみに、この nuget パッケージには、コンパイルされたC/C++ライブラリが含まれている。また、データなどのリソース(アセット)を入れることもできる。
とにかく、私の雑な説明より、上記リンクの説明やサンプルコードを読んで試してみるのがわかりやすいだろう。
最終的には、それほど凝ったアプリではなかったので、Android と iPhone のソースの違いは、ネイティブライブラリを参照している数行だけだった。
DLLNotFoundException に悩まされた・・・
まあ、しかし、初めは、そう簡単にはいかず、Android(エミュレータ) で動かすとDLLNotFoundException が発生して、なんでだろう・・・と2、3日悩んでしまった。
どうやら、ライブラリが参照する DLL が無いと、DLLNotFoundException が発生するらしい(エラーメッセージの通りだが)。数学関数を使っていると、リンク時のオプションに、-lm を付ける、などといったことが必要だった。
Xamarin はいいなと思った点
ネイティブコードも含むコードがプラットフォーム間で共通にできる、という他にいいなと思った点。
- 画面を XAML と呼ばれる XML ベースの言語で記述する点。HTML+CSSで記述するのとそれほど違いはないと思う。XAML でもC#コードでも書ける部分があるが、XAML は C# コードの一部と考えると私にはわかりやすかった。
- nuget のパッケージが豊富な点。標準的な機能で足りないなと思った時は、 nuget.org で探せばよい。乗り遅れているだけなのだが、先人に感謝したい。
- SQLite が標準的に使えるので、ちょっとしたデータを、登録、検索するのに便利。SQLite DB へのアクセスも簡単。 https://docs.microsoft.com/ja-jp/xamarin/get-started/quickstarts/database?pivots=windows あたりが参考になるだろうか。
- C# を使うことになるが、文法がJava/Swiftと大きく違ったものでない点。 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/ あたりを眺めれば、それほど苦労なく理解できることと思う。
実機で動かすところまで辿りつけていないので、もう少し罠があるとは思うが、罠にハマったらまた投稿しようと思う。