ある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/ あたりを眺めれば、それほど苦労なく理解できることと思います。
実機で動かすところまで辿りつけていないので、もう少し罠があるとは思いますが、罠にハマったらまた投稿しようと思います。