Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Embeddinator-4000から学ぶXamarinの基礎
Search
Atsushi Eno
August 19, 2017
Technology
1
7.2k
Embeddinator-4000から学ぶXamarinの基礎
https://jxug.connpass.com/event/60770/
Atsushi Eno
August 19, 2017
Tweet
Share
More Decks by Atsushi Eno
See All by Atsushi Eno
[COSCUP2024] Catching up Trends in Audio App Development
atsushieno
0
390
Building Kotlin Multiplatform Libraries in 2024
atsushieno
0
3.3k
Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話
atsushieno
1
640
building_audio_plugin_ecosystem_on_Android.pdf
atsushieno
0
1.1k
get updated to the latest realtime audio processings knowledge base (2023) (再履修: 2023年までの リアルタイムオーディオ処理)
atsushieno
1
1.1k
learning how DAWs work, with Zrythm
atsushieno
0
1.1k
What for, Where and How to Adopt MIDI 2.0
atsushieno
0
1.2k
audio plugin format study meetup 2022.7.6 (JP)
atsushieno
0
1.6k
CLAPオーディオプラグイン is 何?
atsushieno
1
1.3k
Other Decks in Technology
See All in Technology
TanStack Routerに移行するのかい しないのかい、どっちなんだい! / Are you going to migrate to TanStack Router or not? Which one is it?
kaminashi
0
580
【Pycon mini 東海 2024】Google Colaboratoryで試すVLM
kazuhitotakahashi
2
500
OCI Security サービス 概要
oracle4engineer
PRO
0
6.5k
Platform Engineering for Software Developers and Architects
syntasso
1
520
Terraform未経験の御様に対してどの ように導⼊を進めていったか
tkikuchi
2
430
サイバーセキュリティと認知バイアス:対策の隙を埋める心理学的アプローチ
shumei_ito
0
380
BLADE: An Attempt to Automate Penetration Testing Using Autonomous AI Agents
bbrbbq
0
300
[CV勉強会@関東 ECCV2024 読み会] オンラインマッピング x トラッキング MapTracker: Tracking with Strided Memory Fusion for Consistent Vector HD Mapping (Chen+, ECCV24)
abemii
0
220
B2B SaaSから見た最近のC#/.NETの進化
sansantech
PRO
0
750
Taming you application's environments
salaboy
0
180
The Role of Developer Relations in AI Product Success.
giftojabu1
0
120
いざ、BSC討伐の旅
nikinusu
2
780
Featured
See All Featured
Producing Creativity
orderedlist
PRO
341
39k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Teambox: Starting and Learning
jrom
133
8.8k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
A better future with KSS
kneath
238
17k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Done Done
chrislema
181
16k
[RailsConf 2023] Rails as a piece of cake
palkan
52
4.9k
Transcript
Embeddinator-4000から学ぶ Xamarinの基礎
[email protected]
Introduction
Embeddinator-4000とは?
Xamarinをネイティブで使う? • Native Embedding (Xamarin.Forms) ◦ プラットフォーム固有のコントロールを Xamarin.FormsのLayoutの子として追加 • Forms
Embedding (Xamarin.Forms) ◦ Xamarin.Formsのページをプラットフォーム固有の UIコントロールとして追加 • Embeddinator-4000 ◦ Mono/Xamarinで書いたコードを、プラットフォームネイティブのコードとして利用 Xamarin.Forms Xamarin Native Xamarin Native Xamarin.Forms Native (objc/Java) Xamarin
何が出来るのか • .NET DLLに対応するC/Java/objcバインディングを生成できる • Xamarin.Androidのライブラリ プロジェクトをaarに変換できる ◦ 「Xamarin.Androidのライブラリ プロジェクト」には
Xamarin.FormsのNative Embeddingも含まれる(!) • Mac, iOS (Objective-C)も実装されている ◦ 公式にはまだAndroidのみ ※「aarって何?」という人向けではない
どうやって使うのか? • nugetでembeddinator-4000をインストール • コマンドラインで実行 • mono packages/Embeddinator-4000.0.2.0.80/tools/Embeddinator-4000.exe -platform=Android -gen=Java
-c project/bin/Debug/MyLibrary.dll • mono packages/Embeddinator-4000.0.2.0.80/tools/objcgen.exe -platform=MacOS -gen=Obj-C -c project/bin/Debug/MyLibrary.dll • mono packages/Embeddinator-4000.0.2.0.80/tools/Embeddinator-4000.exe -platform=Linux -gen=c -c project/bin/Debug/MyLibrary.dll
何が出来上がるのか?
どんなライブラリが生成されるのか? (C) using System; public class MyLibrary { public string
Hello (string input) { return "Hello, " + input; } } #include "glib.h" #include "mono_embeddinator.h" #include "c-support.h" typedef MonoEmbedObject MyLibrary; MONO_EMBEDDINATOR_API MyLibrary* MyLibrary_new(); MONO_EMBEDDINATOR_API const char* MyLibrary_Hello(MyLibrary* object, const char* input);
どんなライブラリが生成されるのか? (Java) • Java APIのjarとmonodroidランタイム、アセンブリをassetsに含むaar ◦ resがまだ含まれていない(困る) • hello worldレベルのaarで約10MB
package xamarin_forms_core.xamarin.forms; import com.sun.jna.Pointer; import mono.embeddinator.Runtime; ... public class Page extends VisualElement implements ILayout, IPageController { public Page(Pointer object) { super(object); }
どうやっているのか これを理解するには、Xamarinの動作原理を理解する必要がある 以下の質問にYesと答えられる人にはすぐ概要が分かる • iOSやAndroidのアプリケーション(iOSならXcode + Objective-C、AndroidならAndroid Studio + Java)が、ど
のように作られているのかを理解している • それぞれのプラットフォームで、ネイティブライブラリをビルドして使用できる • monoがembedded APIを用意していることを知っている • Xamarinアプリケーションが各プラットフォームの標準に沿っていると知っている
Xamarin.Android の基礎
embedded mono ネイティブに組み込んで monoを使って.NETコードを 実行できるCライブラリ リフレクションAPIのようなもの [doc] embedding mono scripting
engineなどに便利
monoランタイムによるアプリ起動の流れ main() mscorlibのロード machine.configなどのロード AppDomainの生成 アセンブリのロード CILの実行 この流れは全部mono embedded APIで実装できる
.NETコードのエントリポイントは Main()とは限らない embedded monoなら任意のメソッドから実行可能 .NETにも同様の機能がある( CLR Hosting) ※Silverlight、VSTO $mono hello.exe Hello, C#
iOS/Xamarin.iOS 今回はまだサポートされていないし、時間も足りないので省略… • C/objective-c/swiftのコードはclang+llvmでネイティブにコンパイルされる ◦ 実際に開発者が使うのはXcodeとか、xcodebuildなどのビルドツール • プログラムはmain()から普通に開始 • embedded
monoは `Mono.framework` になっている = リンクするだけ • ObjCRuntime (C API)とembedded monoの間で相互運用 ◦ Xamarin.iOSのAPIは全てこの応用。 strongly typed iOS-ObjCRuntime API
標準的なAndroidアプリはどのように作るか • Android Studioで開発するのが一般的 • JavaまたはKotlinでコーディング • ビルドシステムはGradle • 外部ライブラリはjarまたはaar
◦ jarはコードだけ、aarはネイティブライブラリとかリソースも ◦ パッケージ管理はMaven (主にjcenterサーバー) • ビルドされるアプリケーションはapk ◦ Javaの*.classはdex (dalvik bytecode)に変換 ◦ apkは(zipalignされた)zipアーカイブ
Androidアプリでnative libsを使う ※libmonoはネイティブライブラリ • AndroidはLinuxベースのOS • Android NDKでビルド (tools: gcc
or clang/llvm, libs: bionic libc etc.) • CPUアーキテクチャごとにビルド (armeabi-v7a, aarch64, x86, x86_64, mips) 【CからのJava呼び出し】 ((JNIEnv) env)->CallVoidMethod(klass,...) ※JNIEnvがメタプログラミングの中心 【JavaからのC呼び出し】 boolean native foo(...) ※nativeはJavaのキーワード C#の extern
Xamarin.AndroidとJava/Androidのやり取り ※われわれの Activity.OnCreate() はどう実行されるの か? • XAアプリをビルドすると、Javaから.NETを呼ぶため のJCW (Java callable
wrapper)が生成される ◦ src/md5XXXXXXXXXXXXX/MainActivity.java みたいな感じ ◦ mono embedded APIを間接的に呼び出す libmonodroidの nativeメソッド呼び出し(JNI)として実装されている • AndroidフレームワークがアプリのJCWを呼び出す と関連付けられた.NETコードが実行される
(図解JCW) Android Activity Thread APP JCW Main Activity (.java) onCreate()
C# App Main Activity (.cs) X.A. lib monodroid n_onCreate() "OnCreate()" var method = "GetOnCreate_Landroid_os_Bundle_ Handler"); ... ... mono_runtime_invoke(...); Android側が 呼ぶもの
Androidアプリはどのように実行されるか AndroidフレームワークはJavaで実装されており、 Zygote(Javaもどき)のプロセスで動く。例外は無い • ユーザーがアプリを起動 • AndroidシステムがZygoteプロセスをfork • ActivityThreadクラスがライフサイクルを制御 •
AndroidManifest.xmlを読んで初期化処理 ◦ ContentProviderがあれば実行 (onCreate() など) ◦ Applicationを実行 ◦ main launcher Activityがあれば実行
Xamarin.Androidはどう初期化されるのか? • MonoRuntimeProviderというContentProviderで初期化 ◦ 非公式に一般的な方法 Firebaseなどでも使用 ◦ このタイミングでなくても良い(が初期化以前は使えない) ◦ libmonodroid
▪ embedded monoの初期化 ▪ 全アセンブリのロード ▪ JNI RegisterNatives()でJava/.NETマッピング • JavaアプリケーションループがアプリのJCWを実行 ◦ (JCW = .NETコードをJNI経由で呼び出すJavaクラス) ※Androidの標準的な仕組みに基づいて実現している
Embeddinator-4000
Embeddinator-4000の仕組みの概要 • C(など)のコードからMono/XamarinのマネージドAPIを呼び出す • .NETのアプリに含まれるAPIを「C / Java / Objective-Cから呼び出す」APIを 自動生成してライブラリ化する
• 呼び出されたマネージドコードはmono上で実行される(iOSはAOT-ed) 実は呼び出し層の構成が変わっただけであって、プラットフォーム (objc/Java/C)と.NETの相互運用の仕組みであることに変わりはない Androidが決め打ちのJCWを呼び出す vs. ユーザーが任意のe4k APIを使う
(図解Embeddinator-4000呼び出し) User Java Code e4k Java API Visual Element .java
new xamarin_ forms_core. xamarin.forms. VisualElement() C# App Visual Element (.cs) e4k C API Xamarin. Forms. Core.c "get_Height()" .getHeight() Xamarin_Forms _VisualElement _get_Height()
Cコードの生成 生成ツールは部分的にCppSharpを活用して作られている C++と{好きな言語環境を入れる }の相互運用の自動化は超絶難易度が高いが Cなら簡単(というか、たいてい用意されている) PInvoke、JNI、perl XS、python cypes、node-ffi
Objective-Cコードの生成 • 今回はAndroidの話をするだけでいっぱいいっぱいなので、割愛 • ツールとしてはobjcgen.exe ◦ MonoEmbeddinator4000.exeとは完全に別物の実装 ◦ だいたいTextWriter.WriteLine()で実装している •
MacOSをターゲットにしたら、ライブラリまではビルドできた • iOSはまだ調整が必要そう
Android Javaコードの生成 • 「C/C++の呼び出しを行うJavaコード」を自動生成する • JavaとC++のinteropは現在は一般的にJNIベースの煩雑な手作業 • Embeddinator-4000のコア: e4k C
APIからJNA 呼び出しJavaコードを生成 ◦ JNAのランタイムが実行時にも必要になる(aarに組み込まれる) JNA: Java Native Access (com.sun.jna) Androidをサポートし、事前コード生成を必要としない唯一の選択肢(今回は重要ではない)
考察
Embeddinator-4000の利点 Xamarinアプリケーション開発者にとってのメリット ない それとは関係なく、CppSharpがあるとネイティブ ライブラリの呼び出しが楽になる…かもしれない ※rephrase: C++相互運用は激ムズ ※Xamarinからネイティブライブラリを大量に呼び出していると便利かも
Embeddinator-4000の想定ユーザー(?) • 既存のネイティブアプリでXamarinベースのコードを活用したい人 • 既存のネイティブアプリからXamarinに少しずつコードを移行したい人 • 既存のXamarinアプリからネイティブに土台を移行したい人 • .NET以外の環境でも.NETライブラリの利用を拡大したいライブラリ提供者 ◦
Azure関連のライブラリとか? ◦ ライブラリはMavenに発行することも検討されている
より開かれたXamarin環境 • Embeddinator-4000は「Xamarinでコードを書くとMicrosoft技術に囲い込まれ る」という懸念を晴らすために存在する技術でもある • Xamarinを宣伝したい時に「でもXamarinで全部書くのはこわい…」となった 時に緩和剤のひとつとして機能する側面がある • 「ネイティブで出来るアレやコレができなくなるから…」と言われてXamarinを 利用できなくなっても、埋め込めるチャンスがある
• ただし多用には警戒したほうがよい。相互運用の出入り口が多いとメンテナ ンス地獄になる。ツールの完成度に振り回される • まだ出できたばかりのツールだということを忘れない
まとめ • Xamarinのアプリケーションを埋め込む技術はいろいろあってややこし いので、どれの話をしているか意識して聞いたほうが良い • Xamarinは、iOS/Androidアプリケーションにネイティブコードである libmonoを組み込んで相互運用する技術 • Embeddinatorも、.NET APIを(Xamarinと)mono
embedded API経由で、 相互運用する技術 • レイヤーの重なり方がXamarinアプリケーションと少し違うだけ
宣伝 本セッションの内容は技術書典 3で頒布する Xamarin同人誌(名称未設定)で解説します (2017/10/22 @秋葉原)